views:

59

answers:

3

I've been using the Concurrency Runtime in a C++ static library, and recently wanted to use this library in a C++/CLI project, to take advantage of the Windows Form designer and avoid MFC. Unfortunately, the Concurrency Runtime is not compatible with the /clr switch required in C++/CLI. I tried surrounding the included header files that use the Concurrency Runtime in the "#pragma unmanaged ... #pragma managed" directives, but while that's worked for me with other code in the past, it doesn't seem to work in this case. By which I mean that I get the error:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\concrt.h(27): fatal error C1189: #error :  ERROR: Concurrency Runtime is not supported when compiling /clr.

I'm not super well versed in mixing managed and unmanaged code, so it's possible that there's a work-around that I'm not aware of. But on the other hand, perhaps this is just a silly approach. If it weren't for the fact that I find MFC impossibly complex, and the Form designer so nice and easy, I'd just do pure C++. With a preference to mixing the two, any suggestions?

A: 

You could consider writing a managed GUI, and have it invoke (using PInvoke) an unmanaged DLL: if you can package the Concurrency Runtime, and the code which uses it, as a DLL.

ChrisW
Well, if I understand P/Invoke sufficiently, in order to use the various classes in the C++ library, I would have to do some major work to wrap each class (e.g., http://blogs.msdn.com/b/vcblog/archive/2008/12/08/inheriting-from-a-native-c-class-in-c.aspx). Or is there a simpler way? It almost seems like as much work as creating/maintaining MFC. At least I know some MFC; I've never worked with P/Invoke.
Michael Repucci
@Michael I don't know what your application is, but in the simplest case the DLL only needs to export one function, called `DoAllTheWork()` or something like that. That function is called from the GUI via PInvoke. That function (which is implemented in the DLL) would use the Concurrency Runtime in its implementation, as an implementation detail; it needn't expose all the Concurrency Runtime functions to the GUI.
ChrisW
+2  A: 

Using ConcRT in C++/CLI is explicitly disabled in concrt.h via the statement below because it is not officially supported...

#if defined(_M_CEE)
   #error ERROR: Concurrency Runtime is not supported when compiling /clr.
#endif

You can use PInvoke to work around this as suggested above, or you can also use the pointer to implementation idiom to address this by forward declaring a 'pimpl' class and hide the dependency on concrt.h to a native .cpp file which you can then compile into a lib and link against with the header file.

e.g. in the .h file:

//forward declaration
class PImpl;

class MyClass
{
  ....
  //forward declaration is sufficient because this is a pointer
  PImpl* m_pImpl;
}

e.g. in your .cpp file which compiles into a native lib:

  #include <ppl.h>
  class PImpl
  {
   //some concrt class
   Concurrency::task_group m_tasks;
  }
Rick
Excellent. Just the type of thing I was looking for. Thank you!
Michael Repucci
Your welcome, you can always ask the team on the forums at msdn.com/concurrency (or PM me if I'm not watching stackoverflow at the time).
Rick