C ++ / CLI混合模式DLL创建

时间:2010-04-22 13:45:11

标签: .net c++-cli interop mixed-mode

我有一个本机C ++ DLL,我希望有一个C ++ / CLI包装层。根据我的理解,如果你简单地将C ++ / CLI类添加到项目中,VS将编译为混合模式,但我显然是错误的,因为VS似乎甚至没有触及托管代码。

因此,给定一个预先存在的本机代码库完全,一步一步,您需要创建一个混合模式DLL,以便我可以链接到来自任何.NET语言的代码?

*我需要这样做,因为我的本机代码使用了我无法P / Invoke进入的C ++类。

5 个答案:

答案 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.aspxExporting a C++ class from a DLLhttp://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx)并导出类似C的函数。这种方式也行。

答案 4 :(得分:0)

C ++项目文件需要/ clr选项。我相信,这可以在常规选项卡上为整个项目设置,也可以在单个文件上设置。

一旦指定了clr选项,Visual Studio将使用C ++ / CLI构建该类。