如何将并发运行时与.NET代码混合使用?

时间:2010-08-24 15:52:32

标签: .net visual-studio visual-c++ concurrency c++-cli

我一直在C ++静态库中使用Concurrency Runtime,并且最近想在C ++ / CLI项目中使用此库,以利用Windows窗体设计器并避免使用MFC。不幸的是,并发运行时与C ++ / CLI中所需的/ clr开关不兼容。我尝试在“#pragma unmanaged ... #pragma managed”指令中包含使用并发运行时的包含头文件,但是虽然过去对其他代码有用,但在这种情况下似乎不起作用。我的意思是我得到错误:

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.

我不是非常精通混合托管代码和非托管代码,所以我可能没有意识到这是一种解决方法。但另一方面,也许这只是一种愚蠢的方法。如果不是因为我发现MFC不可能复杂,并且Form设计器如此简单易用,我只会做纯C ++。优先考虑混合两者,有什么建议吗?

5 个答案:

答案 0 :(得分:7)

使用C ++ / CLI中的ConcRT在concrt.h中通过以下语句明确禁用,因为它不受官方支持...

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

您可以使用PInvoke来解决上面建议的问题,或者您也可以使用指向实现惯用语的指针通过向前声明一个'pimpl'类来解决这个问题,并将对concrt.h的依赖隐藏到本机.cpp文件中然后,您可以将其编译为lib并与头文件链接。

e.g。在.h文件中:

//forward declaration
class PImpl;

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

e.g。在您的.cpp文件中编译成本机库:

  #include <ppl.h>
  class PImpl
  {
   //some concrt class
   Concurrency::task_group m_tasks;
  }

答案 1 :(得分:0)

您可以考虑编写托管GUI,并让它调用(使用PInvoke)非托管DLL:如果您可以将并发运行时和使用它的代码打包为DLL。

答案 2 :(得分:0)

我不确定您的并发需求有多详细,但OpenMP工作正常(即您可以合并选项/clr/openmp

array<MyModelResult^>^ model ....;
#pragma omp parallel for
for(int i=0;i<model->Length;i++) {
    model[i] = ComputeModelFor(i);
}

答案 3 :(得分:0)

即使显式禁用了C ++ / CLI中的ConcRT,也可以通过在vcxproj文件中将CompileAsManaged属性设置为false并将PrecompildHeader设置为NotUsing,使用clr支持编译项目并在同一项目中使用一些本机类(I'用VS2013测试了这个:

<ClCompile Include="NativeProcessWithThread.cpp">
  <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
  <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
  <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
  </PrecompiledHeaderFile>
  <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
  </PrecompiledHeaderOutputFile>
  <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
  <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
  <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
  </PrecompiledHeaderFile>
  <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
  </PrecompiledHeaderOutputFile>
</ClCompile>

然后,您可以从托管C ++代码中实例化这样的类:

NativeProcessWithThread nativeProcess = NativeProcessWithThread();

答案 4 :(得分:0)

在使用CLR将C ++链接到C#时,我遇到了同样的问题。 直接在CLR项目中包含的头文件(* .h)中引用以下项目时,就会导致此问题。

#include <ppl.h>
using namespace concurrency;

由于CLR不支持并发,这会在CLR项目构建中产生错误。将这两行移至相应的* .cpp文件即可解决此问题。