32

I have a C++ application which consists of unmanaged C++, managed C++ and c#. In the unmanaged part I'm trying to create a thread safe collection using std::mutex.

However when I use the mutex I get the following error;

error C1189: #error : <mutex> is not supported when compiling with /clr or /clr:pure.

Any idea why I can't use the mutex? Can someone recommend a replacement for it so that I can create a thread-safe unmanaged collection?

Ibrahim Arief
  • 8,742
  • 6
  • 34
  • 54
Miro Bucko
  • 1,123
  • 1
  • 13
  • 26
  • Why don't you use `Monitor`, which is pretty much the managed equivalent of `mutex`? – svick Apr 04 '13 at 21:40
  • But can I use it inside unmanaged code? – Miro Bucko Apr 04 '13 at 21:43
  • 5
    Your best bet is probably to [turn off CLR support](http://stackoverflow.com/questions/808250/vc2008-how-to-turn-clr-flag-off-for-individual-files-in-c-cli-project) for a single compilation unit (cpp file). – Sean Cline Apr 04 '13 at 21:53
  • 2
    A number of similar issues can be resolved by following the steps in this blog article: http://blogs.msdn.com/b/nativeconcurrency/archive/2012/01/05/using-c-amp-code-in-a-c-clr-project.aspx – rwong Apr 04 '14 at 16:49

1 Answers1

21

It is not supported because the std::mutex implementation uses GetCurrentThreadId(). That's a winapi function that is not supposed to be use in managed code since it might be running on a custom CLR host that doesn't use threads to implement threading.

This is the good kind of problem to have, it shows that you are building your code wrong. Your native C++ is being compiled with /clr in effect. Which works rather too well, all C++03 compliant code can be compiled to MSIL and get just-in-time compiled at runtime, just like managed code. You don't want this to happen, your native C++ code should be compiled to machine code and get the compile-time code optimizer love.

Turn off the /clr option for this source code file, and possibly others, in your project. Right-click + Properties, General. If the mutex appears in the .h file that you have to #include in a C++/CLI source file then you have a bigger problem, use an interface or pimpl to hide implementation details.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 4
    *"Turn off the `/clr` option for this source code file... use `#pragma managed` to switch back-and-forth"* - Forgive my ignorance... Can you provide a quick example of it? – jww Jun 30 '15 at 21:39
  • 2
    #pragma managed(push, off) .. native code .. #pragma managed(pop) see https://msdn.microsoft.com/en-us/library/0adb9zxe.aspx – Peter Oct 08 '15 at 10:10
  • 1
    Does the `/clr` option affect native code compiled into a static library and ultimately linked into a managed library? In other words, I compiled a static library without `/clr`. If I compile the library that links that static library with `/clr`, will it affect the static library as well? – void.pointer Jan 18 '17 at 23:37
  • 1
    Yes and no. The actual object files compiled without `/clr` will be compiled as truly native, but any public symbols exposed by the object file (ie. pretty much anything not declared as `static` in the cpp) will have managed symbol thunks declared automatically for them. This is just a symbol name so mostly you don't care, but it does mean that the names of native types and methods will be visible in managed decompilation. Typically this approach of compiling as much as you can into a static non-`/clr` library with a thin `/clr` wrapper is the best way to go. – Miral Feb 23 '17 at 22:45
  • 2
    Is the pimpl solution safe? are'nt you just fooling the compiler? For example C++/CLI code includes a header that holds a pimpl, and the impl uses mutex, when the C++/CLI code calls a function that in turns locks the mutex, isn't the `GetCurrentThreadId` being called from managed code that might not be using threads? – ZivS Aug 15 '18 at 06:20