C++/CLI and <mutex>, <thread>, <future> : fooling the compiler with #pragma managed and _M_CEE

Pierre CHATELIER 11 Reputation points
2022-06-08T07:28:31.123+00:00

When using C++/CLI, trying to use native C++ mutex, thread,future... will result in compilation errors like #error : <mutex> is not supported when compiling with /clr or /clr:pure
There are reasons for that (I guess related to some abstract CLR thread support)

It is not always possible to "#include natives" only in native compilation units (with clr disabled) : declaring types and using classes requires that some include will ultimately spill over clr compilation units

However, if I target a Windows-only desktop app, this should not be a problem.
And it is possible to cheat and fool the compiler.
Instead of

include <mutex>

one can

undef _M_CEE

include <mutex>

define _M_CEE

It just works.

But even if it works, it is not very handy.
One more practical way would be

pragma managed(push,off)

include <mutex>

pragma managed(pop)

but unfortunately it does not work

And an even more practical way would be an additional /clr:letmedowhatiwant compilation flag.

So, a few questions:
-is the trick with _M_CEE a real solution, or is there a high risk of running into problems ?
-if the trick is real, could there be some #pragma that would help push and pop _M_CEE in a more robust way ?
-could there be some compiler improvement to be less cumbersome when dealing with native C++ in C++/CLI ?

A last word : I know that wrapping native code in safe CLR code is recommended, but:
-this might not be good for performance
-the real problem is cascading #include of third-party libraries that might use <future> or <mutex> : we cannot wrap their internals !

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,492 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,579 questions
.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,135 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 58,846 Reputation points
    2022-06-08T15:09:45.033+00:00
    1 person found this answer helpful.
    0 comments No comments

  2. Pierre CHATELIER 11 Reputation points
    2022-06-09T12:48:05.39+00:00

    It looks like a good technical answer, but it lacks many details.
    It states that crossing the border between Managed and unmanaged will silently call some LoadLibrary() and thus that dead locks could occur when dealing with mutexes, but it is unclear:
    -why the LoadLibrary() lock would remain locked before the mutex is finally locked itself
    -why the dependencies loaded by the silent LoadLibrary() calls could not be preloaded with a dry-run
    -how it would not be a problem at all if Managed/unmanaged boundaries are already crossed when native [shared]mutex and threads are internals of this party libraries that we just want to import in a C++/CLI project

    Should I switch to the other thread (https://developercommunity.visualstudio.com/t/shared-mutex-and-clr/469913) to backport thoses questions ?