2010-08-24 55 views
4

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

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非常复杂,并且表单设计器非常简单,我只需要纯C++。有兴趣混合两者,有什么建议吗?

+1

请不要让我们猜什么“不工作”的意思。 – 2010-08-24 16:36:14

+0

对不起。上面编辑。 – 2010-08-24 18:03:13

回答

6

在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并链接到头文件。

例如在.h文件中:

//forward declaration 
class PImpl; 

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

例如在您的.cpp文件,其编译成一个本地库:

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

优秀。只是我正在寻找的东西的类型。谢谢! – 2010-10-17 19:57:14

+0

欢迎您随时咨询msdn.com/concurrency论坛上的团队(或者如果我当时没有在看stackoverflow的话,请告诉我)。 – Rick 2010-10-18 00:32:15

+0

我一直在试图公开其中一个task_group类的运行方法,但它使用了一个模板。 AFAIK你必须声明整个函数,如果它使用模板,这意味着它是不可能隐藏使用ppl.h.或者我错过了什么? – 2012-05-16 20:20:09

0

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

+0

那么,如果我充分理解P/Invoke,为了在C++库中使用各种类,我将不得不做一些主要工作来包装每个类(例如http://blogs.msdn.com/b/ vcblog /存档/ 2008/12/08 /继承从 - 一个天然-c级合c.aspx)。还是有更简单的方法?它看起来像创建/维护MFC一样多。至少我知道一些MFC;我从来没有与P/Invoke合作过。 – 2010-08-24 18:14:31

+1

@Michael我不知道你的应用程序是什么,但在最简单的情况下,DLL只需要导出一个名为'DoAllTheWork()'的函数或类似的东西。该函数通过PInvoke从GUI中调用。该函数(在DLL中实现)将在其实现中使用并发运行时,作为实现细节;它不需要向GUI显示所有的并发运行时功能。 – ChrisW 2010-08-24 19:14:20

0

我不知道你的并发需求多么详尽的,但OpenMP正常工作(即,您可以结合选项/clr/openmp

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

即使C++/CLI中的ConcRT被显式禁用,您也可以使用clr支持来编译项目,并在同一项目中拥有一些本地类,方法是将CompileAsManaged属性设置为false,并在您的vcxproj文件中将PrecompildHeader设置为NotUsing我已经用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();