14

我有一个本机 C++ DLL,我想要一个 C++/CLI 包装层。据我了解,如果您简单地在项目中添加一个 C++/CLI 类,VS 将编译为混合模式,但我显然错了,因为 VS 似乎甚至没有触及托管代码。

那么,给定一个预先存在的本机代码库,您需要逐步创建混合模式 DLL,以便我可以从任何 .NET 语言链接到该代码

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

4

6 回答 6

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(); 
    }
};
于 2010-04-22T14:00:46.203 回答
6

防止 /clr 影响现有代码的一个好选择是将所有现有代码编译到本机静态库中,然后在 C++/CLI dll 的链接步骤中包含该静态库。

于 2010-04-24T05:53:57.670 回答
1

开始一个新的 C++/CLI 项目,然后将您的本机类移至该项目。

于 2010-04-22T13:50:30.060 回答
1

无需在项目级别打开“公共语言运行时支持”,只需查看文件的属性并转到 C/C++ | 就可以逐个文件启用它。一般 | 通用语言支持。

这可能会使您的本机代码和 C++/CLI 代码更容易放在同一个项目中,而不是创建一个仅包含包装器的单独 C++/CLI DLL,或者必须使用大量托管/非托管编译指示。

因此,只需在您要编写的 C++/CLI .NET 包装类上执行此操作即可。

于 2012-03-13T12:44:49.867 回答
0

如果您有原生 C++ 的 DLL 源代码,则可以在混合模式下使用托管 C++。一段时间以来,Microsoft 有一个将一些著名的 DirectX 游戏迁移到 .NET 的参考项目。一种在混合模式下使用托管 C++。部分代码被重写为托管代码。一部分很快被更改为在混合模式下编译为 C++,一部分被编译为汇编代码(由于性能原因),但也直接在托管代码内部用作不安全代码。这种迁移结果在最终应用程序中获得了非常好的性能。通过这种方式,您不必花时间在本机代码和托管代码之间进行封送处理。安全和不安全托管代码之间的编组非常快。可能你也应该选择这种方式?

另一种从托管 .NET 代码中的 DLL 调用本机代码的方法是众所周知的。每个 C++ 函数都有未修饰的名称(使用http://www.dependencywalker.com/来查看)。如果您的 C++ DLL 导出类而不是类 C 函数,则此 DLL 设计不佳。设计良好的 DLL 要么导出类 C 函数,要么导出 COM 接口。如果你有这样“坏”的 DLL 并且不想花时间写一个 COM,你可以很容易地再写一个 DLL 来扮演 stub 的角色。此 DLL 导入所有 C++ 类(请参阅http://msdn.microsoft.com/en-us/library/81h27t8c.aspx、Exporting a C++ class from a DLLhttp://www.codeproject.com/KB/cpp/ howto_export_cpp_classes.aspx)从“坏”的 DLL 中导出并导出类 C 函数。这种方式也是可以的。

于 2010-04-22T14:15:57.507 回答
0

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

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

于 2010-04-22T14:58:56.767 回答