C++ 使用/clr:pure项目中的混合DLL
我正在构建一个带有Dll的项目 Dll必须支持本机代码,因此我将其声明为/clr。 我的项目最初也是a/clr项目,一切都很好。然而,我想包括一些NUnit测试,所以我不得不将我的主项目从/clr切换到/clr:pure 一切仍在编译,但任何Dll调用都会生成运行时错误。当我恢复到/clr时,一切都正常 在my Dll中,导出的函数声明如下:C++ 使用/clr:pure项目中的混合DLL,c++,dll,visual-studio-2005,clr,mixed-mode,C++,Dll,Visual Studio 2005,Clr,Mixed Mode,我正在构建一个带有Dll的项目 Dll必须支持本机代码,因此我将其声明为/clr。 我的项目最初也是a/clr项目,一切都很好。然而,我想包括一些NUnit测试,所以我不得不将我的主项目从/clr切换到/clr:pure 一切仍在编译,但任何Dll调用都会生成运行时错误。当我恢复到/clr时,一切都正常 在my Dll中,导出的函数声明如下: #define DllExport __declspec( dllexport ) DllExport bool DisplayScan(bool b
#define DllExport __declspec( dllexport )
DllExport bool DisplayScan(bool bShow, bool bAllPasses) { }
我还创建了一个.def文件,其中包含所有导出函数的真实名称
LIBRARY "Controller"
EXPORTS
DisplayScan
从我的主项目中,我的导入声明如下:
#define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool DisplayScan(bool bShow, bool bAllPasses)
有人遇到过这样的问题吗?好了,现在一切都正常了 事实上,它从一开始就在起作用 寓意:不要试图将char*转换为std::string
奇怪的事情:在从函数返回之前,在/clr中是可以的。它立即在/clr:pure中崩溃好,现在一切正常 事实上,它从一开始就在起作用 寓意:不要试图将char*转换为std::string
奇怪的事情:在从函数返回之前,在/clr中是可以的。它在/clr:pure中立即崩溃基本上你正在做一些不受支持的事情/clr:纯DLL和本机DLL导出。从纯程序集中引用的As无法导出可从本机函数调用的函数,因为纯程序集中的入口点使用_clrcall调用约定
我不确定最好的解决办法。不过,通过一点实验,您可能可以利用带有/clr选项的_clrcall调用约定。这可能有用。从我收集到的信息来看,您应该能够导出这些托管类,并从托管程序集(如托管NUnit测试项目)中使用它们,但应使用不同的方法签名保留非托管导出。请记住,一旦您通过导出公开任何.net类,它就需要使用_clrcall调用约定。基本上您正在做一些不受支持的事情/clr:纯DLL和本机DLL导出。从纯程序集中引用的As无法导出可从本机函数调用的函数,因为纯程序集中的入口点使用_clrcall调用约定
我不确定最好的解决办法。不过,通过一点实验,您可能可以利用带有/clr选项的_clrcall调用约定。这可能有用。从我收集到的信息来看,您应该能够导出这些托管类,并从托管程序集(如托管NUnit测试项目)中使用它们,但应使用不同的方法签名保留非托管导出。请记住,只要通过导出公开任何.net类,它就需要使用uu clrcall调用约定。您的问题是调用约定CallingConvention=CallingConvention::Cdecl。。。像这样定义您的函数,或者使用stdcall或clrcall,clecl代表纯C 问题是:
定义函数extern not static您的问题是调用conventionCallingConvention=CallingConvention::Cdecl。。。像这样定义您的函数,或者使用stdcall或clrcall,clecl代表纯C 问题是: 定义函数extern not static的优点/clr:pure 更好的性能:因为纯程序集只包含MSIL,所以没有本机函数,因此不需要托管/非托管转换。通过P/Invoke进行的函数调用是此规则的例外 AppDomain感知:托管函数和CLR数据类型存在于应用程序域中,这会影响它们的可见性和可访问性。纯程序集是域感知的_declspecappdomain对于每种类型都是隐含的,因此从其他.NET组件访问它们的类型和功能更容易、更安全。因此,与混合程序集相比,纯程序集更容易与其他.NET组件进行互操作 非磁盘加载:纯程序集可以加载到内存中,甚至可以流式加载。这对于将.NET程序集用作存储过程至关重要。这与混合程序集不同,混合程序集依赖于Windows加载机制,必须存在于磁盘上才能执行 反射:不可能对混合可执行文件进行反射,而纯程序集提供完全反射支持。有关更多信息,请参阅反射C++/CLI 主机可控性:由于纯程序集仅包含MSIL,因此在承载CLR并修改其默认行为的应用程序中使用时,它们的行为比混合程序集更可预测和灵活 /clr的限制:纯 本节介绍/clr:pure当前不支持的功能 非托管函数无法调用纯程序集。因此,纯程序集无法实现COM接口或公开本机回调。纯程序集无法导出函数 通过uuu declspecdllexport或.DEF文件进行离子交换。此外,使用_clrcall约定声明的函数不能通过_declspecdlimport导入。本机模块中的函数可以从纯程序集中调用,但纯程序集中不能公开本机可调用函数,因此必须通过混合程序集中的托管函数来公开纯程序集中的功能。有关详细信息,请参见如何:迁移到/clr:pure C++/CLI VisualC++中纯模式编译不支持ATL和MFC库。
纯.NETMAMP不被接受为VisualC++链接器的输入。但是,链接器接受纯.obj文件,.obj文件包含netmodules中包含的信息超集。有关详细信息,请参见.netmodule文件作为链接器输入
不支持编译器COM支持导入,因为这会将非托管指令引入纯程序集中 对于纯程序集,对齐和异常处理的浮点选项是不可调整的。因此,无法使用u declspecalign。这会导致某些头文件(如fpieee.h)与/clr:pure不兼容 使用/clr:pure编译时,PSDK中的GetLastError函数可能会给出未定义的行为。使用/clr:pure的优点 更好的性能:因为纯程序集只包含MSIL,所以没有本机函数,因此不需要托管/非托管转换。通过P/Invoke进行的函数调用是此规则的例外 AppDomain感知:托管函数和CLR数据类型存在于应用程序域中,这会影响它们的可见性和可访问性。纯程序集是域感知的_declspecappdomain对于每种类型都是隐含的,因此从其他.NET组件访问它们的类型和功能更容易、更安全。因此,与混合程序集相比,纯程序集更容易与其他.NET组件进行互操作 非磁盘加载:纯程序集可以加载到内存中,甚至可以流式加载。这对于将.NET程序集用作存储过程至关重要。这与混合程序集不同,混合程序集依赖于Windows加载机制,必须存在于磁盘上才能执行 反射:不可能对混合可执行文件进行反射,而纯程序集提供完全反射支持。有关更多信息,请参阅反射C++/CLI 主机可控性:由于纯程序集仅包含MSIL,因此在承载CLR并修改其默认行为的应用程序中使用时,它们的行为比混合程序集更可预测和灵活 /clr的限制:纯 本节介绍/clr:pure当前不支持的功能 非托管函数无法调用纯程序集。因此,纯程序集无法实现COM接口或公开本机回调。纯程序集无法通过uu declspecdllexport或.DEF文件导出函数。此外,使用_clrcall约定声明的函数不能通过_declspecdlimport导入。本机模块中的函数可以从纯程序集中调用,但纯程序集中不能公开本机可调用函数,因此必须通过混合程序集中的托管函数来公开纯程序集中的功能。有关详细信息,请参见如何:迁移到/clr:pure C++/CLI VisualC++中纯模式编译不支持ATL和MFC库。纯.NETMAMP不被接受为VisualC++链接器的输入。但是,链接器接受纯.obj文件,.obj文件包含netmodules中包含的信息超集。有关详细信息,请参见.netmodule文件作为链接器输入
不支持编译器COM支持导入,因为这会将非托管指令引入纯程序集中 对于纯程序集,对齐和异常处理的浮点选项是不可调整的。因此,无法使用u declspecalign。这会导致某些头文件(如fpieee.h)与/clr:pure不兼容 使用/clr:pure编译时,PSDK中的GetLastError函数可能会给出未定义的行为