我正在用C++/CLI包装一个纯非托管VC++ 9项目,以便从.NET应用程序中清楚地使用它。我知道如何编写wrappers和非托管代码can be executed from .NET,但我无法完全理解的是:
/clr-marked托管DLL中。我需要使用普通的VC++编译器将它编译成一个独立的DLL。extern?是这么简单,还是有更多的复杂性?发布于 2013-03-24 12:49:10
您可以从一个普通的本机C++项目开始(比如从十多年前的VisualStudio6.0导入),当您今天构建它时,它将链接到VC运行时的当前版本。
然后您可以向它添加一个新的foo.cpp文件,但是要配置该文件,以便启用/CLR标志。这将导致编译器从该文件生成IL,并链接到一些额外的支持中,这些支持将导致.NET框架在启动时加载到进程中,因此它可以编译并执行IL。
应用程序的其余部分仍然像以前一样以本地方式编译,并且完全不受影响。
事实上,即使是“纯”的CLR应用程序也是混合的,因为CLR本身就是(显然)本机代码。一个混合的C++/CLI应用程序只允许添加更多的本机代码来与一些CLR托管的代码共享进程,从而扩展了这一点。它们在整个过程中都是共存的。
如果您使用声明创建了一个标头foo.h:
void bar(int a, int b);您可以在本机代码或foo.cpp CLR代码中自由实现或调用这一点。编译器/链接器组合负责所有事务。不需要做任何特殊的事情从CLR代码中调用本机代码。
您可能会得到有关不兼容开关的编译错误:
/ZI -用于编辑和继续的程序数据库,将其更改为仅用于程序数据库/Gm -您需要禁用最小重建/EHsc - C++异常,将其更改为有SEH异常(/EHa)/RTC -运行时检查,将其更改为默认/GR- -运行时类型信息-将其更改为On (/GR)所有这些更改只需要对特定的启用/CLR的文件进行。
发布于 2013-03-24 19:41:50
正如丹尼尔提到的,您可以在文件级别上微调您的设置。您也可以在文件中使用“#务实管理”,但我不会无缘无故地这样做。
请记住,您可以创建一个完整的混合模式程序集。这意味着,您可以将您的本机代码编译成此文件,并在此代码周围加上一些C++/CLI包装器。最后,您将拥有与本机Dll相同的文件和所有导出的本机符号,同时具有完整的.NET程序集(公开C++/CLI对象)!
这也意味着,只要考虑到文件之外的本地客户端代码,您就只需要关心导出。混合dll/程序集中的C++/CLI代码可以使用通常的访问规则访问本机数据结构(简单地包括报头)
因为您提到了这一点,所以我这样做是为了一些重要的原生C++类层次结构,包括相当数量的DirectX代码。所以这里没有主要问题。
我建议不要在.NET驱动的环境中使用pInvoke。是的,很管用。但是对于任何不平凡的事情(比如10个以上的函数),使用C++/CLI提供的OO方法肯定会更好。您的C#客户端开发人员将非常感激。您可以使用C++/CLI中的所有.NET内容,如委托/属性、托管线程等。从VS 2012开始,也有一些可用的Intellisense。
发布于 2013-03-24 12:31:39
可以使用PInvoke从非托管DLL调用导出函数。这就是从.Net访问非托管Windows的方式。但是,如果导出的函数使用C++对象,而不仅仅是普通的C数据结构,则可能会遇到问题。
似乎还有C++互操作技术可以对您有用:http://msdn.microsoft.com/en-us/library/2x8kf7zx(v=vs.80).aspx。
https://stackoverflow.com/questions/15598445
复制相似问题