【问题标题】:How to export a C++ class library to C# using a dll?如何使用 dll 将 C++ 类库导出到 C#?
【发布时间】:2026-02-17 18:40:01
【问题描述】:

在我之前的版本游戏引擎中,我为 C# 的游戏编辑器移除了主要功能。现在,我开始用静态库修改游戏引擎。已经在 C++ 中创建了一个动态库,用于将 DLLEXPORT 用于 C#。刚才我想测试较新的函数并从 C++ 创建一个 DLL 文件。因为 DLL 包含类,所以我想知道如何使用 DLL Export。我会这样做吗:

[DLLEXPORT("GameEngine.dll", EntryPoint="SomeClass", Conventional=_stdcall)]
static extern void functionFromClass();

我感觉可能是 DLLImport 而不是 DLLExport。我想知道我该怎么做?我在想的另一种方式是因为我已经准备好 C++ 中的 DLL,以便进入 C# 类库。我可以将新引擎保留为一个库,并将该库与旧的 DLL C++ 文件链接。

EntryPoint 不能指向函数所在的类吗?

【问题讨论】:

    标签: c++ c# import dll


    【解决方案1】:

    你实际上不能像这样直接导出 C++ 类。

    static extern void functionFromClass();
    

    C++ 的问题在于它没有通用定义的 ABI(应用程序二进制接口)。所以为了让其他语言理解你的 C++ 库 ABI,你需要用 C 函数来包装它(几乎所有其他语言都理解 C)。

    C 的问题在于它不理解类。另一方面,C++ 对象需要将this 指针作为参数传递给它们的成员函数。所以为了用 C 接口包装你的 C++ 类。您需要显式处理传递this 参数,并定义类似于构造函数和析构函数的函数。

    你需要这样做:

    //Header File Foo.h
        struct Foo; // Forward Declaration Only
        Foo*  createFoo( /* parameters */ );
        void  destroyFoo( Foo* obj );
        int Func( Foo* obj, int i ); // obj should take this pointer 
        float Func2( Foo* obj, float i, float j );
    

    这样实现

    #include "Foo.h"
    extern "C" 
    {
      Foo* createFoo( const char * s )
      {
        return reinterpret_cast<Foo*>( new Foo( s ) );
      }
      void destroyFoo( Foo* obj )
      {
        delete reinterpret_cast<Foo*>(obj );
      }
      int Func( Foo* obj, int i )
      {
        return reinterpret_cast<Foo*>(obj)->Func(i);
      }
    }
    

    最后,您可以将导出的 C 函数包装在 C# 类中,这样就可以回到传统的面向对象方式。

    请注意,我什至没有提到继承或多态性。

    【讨论】:

    • +1。时间过得真快 :) 最近,我一直在使用 CLI 来插入非托管代码和托管代码。我还没有深入研究 COM 开发。我可能会冒险进入它。 :)
    【解决方案2】:

    您不能将本机 C++ 类直接导入 C#。它们需要以一种或另一种方式包装。您可以使用 C 样式的非成员函数包装它们。您需要导出创建和销毁实例的函数。总而言之,这是一个非常可怕的过程。

    执行此操作的明智方法是将本机 C++ 代码编译成混合模式 C++/CLI 程序集。然后,您可以将该功能公开为托管 ref 类。然后互操作变得微不足道,您无需手动编写 p/invoke 声明。

    【讨论】:

    • 所以换句话说,在创建托管 C++ DLL 文件时,将本机代码包装在托管 CLI C++ 中然后转到 C# 会更简单吗?这将使地狱变得更加容易,此外,始终如一地旋转不会是一件麻烦事。
    • 一旦您开始想要包装 C++ 类,那么您就无法使用纯 C# 端 p/invoke 来实现。您需要编写一些 C++ 代码。只要您需要这样做,C++/CLI 总是最简单的解决方案。如果您想包装以供 .net 以外的其他用户使用,则 COM 将是一个候选者,但如果不是,则 C++/CLI 获胜。
    • 我最喜欢你的回答,因为之前的引擎最初是用混合的 Native 和 CLI 代码包装核心游戏引擎。我知道这对于 DLL 来说将是一个非常长的 H 文件,但我现在将坚持使用它,然后选择最适合在游戏方面实现的功能。我不确定为什么当我创建单独的头文件时 C++ 会变得很挑剔,但我会随着我的进展而弄清楚这一点。但是感谢大家的参与和帮助!
    • 对于我正在做的这个当前项目,CLI 是最好的方法。出于学习目的,我最终将不得不研究 COM Interloping。 :)
    【解决方案3】:

    我建议看看 COM Objects 并使用 COM Interop 在 Cpp 和 C# 程序之间进行通信。

    【讨论】:

    • +1。谢谢。我最终将不得不深入研究 COM 开发。这是我可能会觉得学习很有趣的东西。到目前为止,我一直在使用 CLI 将本机 C++ 与托管代码进行交互。 :)