2008-11-14 76 views
1

我正在与一个Dll一起构建一个项目。使用/ clr中的混合DLL:纯项目

该Dll必须支持本机代码,所以我将其声明为/ clr。 我的项目最初也是一个/ clr项目,一切都很好。不过,我想包括一些NUnit测试,所以我不得不将我的主项目从/ clr切换到/ clr:pure。

一切仍然编译,但任何Dll调用都会生成运行时错误。当我恢复到/ CLR一切正常

在我的DLL,导出的函数声明如下:

#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) 

有人遇到过这样的问题吗?

回答

3

好吧一切正在工作

事实上,它一直在努力从一开始。

道德:直到你从函数返回其在/ CLR OK:不要试图施放一个char *成的std :: string

奇怪的事情。它立即崩溃在/ clr:纯

3

基本上你正在做一些不被支持;/clr:纯和本地DLL导出。从this MSDN article引用“由于纯汇编中的入口点使用__clrcall调用约定,纯汇编不能导出可从本机函数调用的函数。”

我不确定最佳的解决方法。但是,通过一些实验,您可以利用/ clr选项利用__clrcall调用约定。 Here's a link可能有用。从我可以收集的内容中,您应该能够导出这些托管类并从托管程序集(如托管的NUnit测试项目)中使用它们,但请使用不同的方法签名保留您的非托管导出。请记住,只要通过导出公开任何.net类,它就需要使用__clrcall调用约定。

0

您的问题呼唤conventionCallingConvention = CallingConvention :: CDECL ...定义函数一样,或使用STDCALL或clrcall,clecl是纯C

或问题是在这里: 定义函数extern不是静态

1

优势/ CLR的:纯

更好的性能:由于纯组件只包含MSIL,没有本机的功能,因此没有管理/非托管的转变是必要的。 (通过P/Invoke进行的功能调用是此规则的一个例外。)

AppDomain Awareness:管理函数和CLR数据类型存在于应用程序域内,这会影响其可见性和可访问性。纯的程序集是可识别域的(每种类型都隐含有__declspec(appdomain)),因此从其他.NET组件访问它们的类型和功能更加简单和安全。因此,纯组件与混合程序集相比,可以更轻松地与其他.NET组件进行交互操作。

非磁盘加载:纯粹的程序集可以加载到内存中,甚至流式传输。这对使用.NET程序集作为存储过程至关重要。这与混合程序集不同,后者由于依赖于Windows加载机制,必须存在于磁盘上才能执行。

反思:不可能反映混合的可执行文件,而纯粹的程序集提供全面的反射支持。有关更多信息,请参阅反射(C++/CLI)。

主机可控性:因为纯粹的程序集只包含MSIL,所以在托管CLR并修改其默认行为的应用程序中使用时,它们的行为比混合程序集更具可预测性和灵活性。纯

本节介绍当前不/ CLR支持的功能:纯/ CLR的

限制。

纯组件不能由非托管函数调用。因此,纯粹的程序集不能实现COM接口或公开本机回调。纯组件不能通过__declspec(dllexport)或.DEF文件导出函数。此外,使用__clrcall约定声明的函数不能通过__declspec(dllimport)导入。本地模块中的函数可以从纯集合中调用,但纯集合不能公开纯集合函数,因此在纯集合中公开功能必须通过混合程序集中的托管函数完成。有关更多信息,请参见如何:迁移到/ clr:pure(C++/CLI)。

在Visual C++中纯模式编译不支持ATL和MFC库。

Pure .netmodules不被接受为Visual C++链接器的输入。但是,链接器接受纯.obj文件,而.obj文件包含netmodules中包含的信息的超集。有关更多信息,请参阅.netmodule文件作为链接器输入。

不支持编译器COM支持(#import),因为这会将非托管指令引入到纯组件中。

用于对齐和异常处理的浮点选项对于纯组件不可调整。因此,不能使用__declspec(align)。这会呈现一些头文件,如fpieee.h,与/ clr:pure不兼容。

使用/ clr:pure编译时​​,PSDK中的GetLastError函数可能会导致未定义的行为。