【问题标题】:Writing a C++ DLL that a C# .NET Application can call?编写 C# .NET 应用程序可以调用的 C++ DLL?
【发布时间】:2026-02-12 11:50:01
【问题描述】:

情况就是这样。我正在用 C++ 编写一个后端应用程序,而我的同事正在使用 C# 作为前端。基本上,我的后端应用程序对从 C# 前端接收到的图像进行图像处理,并返回一个包含图像数据的文本文件。 我们之前所做的是将图像写入磁盘并使用图像的文件路径作为参数调用 C++ 应用程序。但是,这种从磁盘写入/读取已成为瓶颈,因此我们希望将 C++ 应用程序转换为 DLL。

在基本层面上,我想要的是通过 DLL 将我的 C++ 应用程序中的单个方法公开给 C#(C# 应用程序是基于 Web 的):

int ProcessImage(System::Bitmap^ image, System::String ^results)

我该怎么做呢?我正在使用 VC++ Express 2008,我的 C++ 代码目前使用 CLR 编译(虽然我在里面混合了很多本机 C++ 代码)。

我一直在网上四处寻找,但仍然坚持如何做到这一点。我认为 C++/CLI DLL 是最好的选择,但我该怎么做呢? Writing a DLL in C/C++ for .Net interoperability

【问题讨论】:

标签: c# .net dll c++-cli interop


【解决方案1】:

如果您将 C++ 函数标记为“C”函数,则它可以由 PInvoke 调用。

您的 C 函数将如下所示:

extern "C" __declspec(dllexport) int Test() {
    return 1;
}

您的 C# 引用将如下所示:

[DllImport("test.dll")]
public static extern int Test();

如果你的 C++ 函数是实例成员,那么你仍然可以这样做,但需要一些技巧。

【讨论】:

  • 您还应该将 __stdcall 添加到 C++ 函数,或将 CallingConvention 添加到 DllImport
  • 我相信 extern "C" 可以防止函数/方法名称混淆。
  • 只有全局命名空间中的函数才能以与 p/invoke 兼容的方式导出。忘记与类有关的任何事情,无论您是指类的成员函数(静态或非静态)还是参数或返回值中的类类型。
  • 感谢您的回复,但我认为这不适用于我正在尝试做的事情。如何使用此方法通过引用传递图像并以字符串形式接收结果?
【解决方案2】:

我终于明白了。你需要做的是:

  1. 在您的 C++ 项目中,将 Visual C++ 中的选项设置为使用 clr pure 编译,这使项目成为 C++/CLI 之一
  2. 在您的 C++ 项目中,通过创建公共 ref 类来公开方法:

    public ref class Interop
    {
    public:
        //! Returns the version of this DLL
        static System::String^ GetVersion() {
            return "3.0.0.0";
        }
    
        //! Processes an image (passed by reference)
        System::Int32^ Process(Bitmap^ image);
    }
    
  3. 在 C# 程序中,添加对您编译的 C++ DLL 的引用
  4. 在 C# 程序中,调用这些方法(即Interop::Process(myBitmapInCS)

我相信这种方法称为“隐式 P/Invoke” 希望这会有所帮助!

【讨论】: