我有一个本机C ++ DLL,我希望有一个C ++ / CLI包装层。根据我的理解,如果你简单地将C ++ / CLI类添加到项目中,VS将编译为混合模式,但我显然是错误的,因为VS似乎甚至没有触及托管代码。
因此,给定一个预先存在的本机代码库完全,一步一步,您需要创建一个混合模式DLL,以便我可以链接到来自任何.NET语言的代码?
*我需要这样做,因为我的本机代码使用了我无法P / Invoke进入的C ++类。
答案 0 :(得分:18)
嗯,不,在您告诉C ++ / CLI编译器您的旧DLL是用非托管代码编写之前,它不会成为混合模式。哪个应该引人注意,你应该从非托管DLL导出中获得链接器错误。您需要使用#pragma managed:
#pragma managed(push, off)
#include "oldskool.h"
#pragma comment(lib, "oldskool.lib")
#pragma managed(pop)
using namespace System;
public ref class Wrapper {
private:
COldSkool* pUnmanaged;
public:
Wrapper() { pUnmanaged = new COldSkool; }
~Wrapper() { delete pUnmanaged; pUnmanaged = 0; }
!Wrapper() { delete pUnmanaged; }
void sampleMethod() {
if (!pUnmanaged) throw gcnew ObjectDisposedException("Wrapper");
pUnmanaged->sampleMethod();
}
};
答案 1 :(得分:6)
防止/ clr影响现有代码的一个好方法是将所有现有代码编译到本机静态库中,然后在C ++ / CLI dll的链接步骤中包含该静态库。
答案 2 :(得分:2)
开始一个新的C ++ / CLI项目,然后将您的本机类移动到它。
答案 3 :(得分:0)
如果您具有本机C ++的DLL源代码,则可以在混合模式下使用托管C ++。微软已经有一段时间将一些着名的DirectX游戏迁移到.NET的参考项目。一个在混合模式下使用托管C ++。部分代码被重写为托管代码。一部分很快被改为在混合模式下编译为C ++,一部分被编译为汇编代码(由于性能原因),但也直接在托管代码内部用作不安全的代码。因此,这种迁移会在最终应用程序中实现非常好的性能。这样,您就不会花时间在本机代码和托管代码之间进行编组。安全和不安全的托管代码之间的编组很快。也许你也应该选择这种方式?
另一种在manged .NET代码中从DLL调用本机代码的方法是众所周知的。每个C ++函数都有未修饰的名称(使用http://www.dependencywalker.com/来查看)。如果您的C ++ DLL导出类而不是类C函数,则此DLL设计不当。设计良好的DLL既可以导出类似C的函数,也可以导出COM接口。如果你有这样的“坏”DLL并且不想花时间编写COM,你可以轻松编写一个将扮演存根角色的DLL。此DLL从“坏”DLL导入所有C ++类(例如,请参阅http://msdn.microsoft.com/en-us/library/81h27t8c.aspx,Exporting a C++ class from a DLL和http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx)并导出类似C的函数。这种方式也行。
答案 4 :(得分:0)
C ++项目文件需要/ clr选项。我相信,这可以在常规选项卡上为整个项目设置,也可以在单个文件上设置。
一旦指定了clr选项,Visual Studio将使用C ++ / CLI构建该类。