【问题标题】:How to Expose C Static Library to .Net?如何将 C 静态库公开给 .Net?
【发布时间】:2016-05-21 01:36:39
【问题描述】:

向 C 和 .Net 公开 C++ 函数的步骤是什么?我想在 C++、C 和 .Net 中为 32 位和 64 位构建使用相同的函数名称。

我发布这个问题和答案是因为我在任何地方都没有发现这些技术的文档。

【问题讨论】:

  • 这是一个错误,C++ 编译器使用的名称修饰非常有助于确保在函数声明更改时不会出现严重错误。这导致的堆栈不平衡是一个非常难以解决的问题。除了函数声明上的extern "C" 之外,它只需要其他任何东西,pinvoke marshaller 已经知道要寻找普通的 C 函数装饰。

标签: c++ .net dll static-libraries pragma


【解决方案1】:

步骤如下:

  1. 将 C++ 函数公开为 C 静态库 (.lib)。

  2. 使用 #pragma 语句将 lib 的函数投影到 DLL 中。

  3. 使用 .Net 的 DllImport 属性公开 DLL 的函数。

例如,见this github project.

步骤 1. 创建一个静态库项目。创建一个将每个函数公开为 C 函数的 C++ 文件。

extern "C" {
  void vfunc(void) { return; }
  int ifunc(int i) { return i; }
}

第 2 步。创建一个 DLL 项目。将静态库指定为“附加依赖项”。创建一个 C 文件并放入 #pragma 语句以将每个静态库函数投影到 .DLL 中。您需要定义两个#pragmas,一个用于32 位,另一个用于64 位。不同之处在于 32 位需要在函数名称前加上前导下划线。无需代码,只需#pragmas。

#ifdef _M_X64
#define Alias(func) comment(linker, "/export:" func "=" func)
#else
#define Alias(func) comment(linker, "/export:" func "=_" func)
#endif

#pragma Alias("vfunc")
#pragma Alias("ifunc")

第 3 步。创建一个 .Net 项目。使用DllImport 属性来暴露每个函数。

class Program
{
    [DllImport("c-dll.dll")]
    extern static void vfunc();
    [DllImport("c-dll.dll")]
    extern static void ifunc();
    static void Main(string[] args)
    {
        vfunc();
        int i = ifunc(1);
    }
}

虽然使用这些技术进行编码很简单,但您需要对解决方案和项目文件进行大量编辑。

  1. 设置解决方案的正确构建顺序。 DLL 将依赖于静态库。 .Net 项目将依赖于 DLL。

  2. 手动编辑 DLL 项目文件以将 32 位和 64 位 DLL 构建到单独的目录中(例如 Win32\Debug、x64\Debug)。

  3. 手动编辑 .Net 项目文件以创建用于 x86/x64 和调试/发布组合的部分(共 4 个)。不要使用AnyCPUDllImport 不适用于 AnyCPU。仅使用 x86/x64。

  4. 手动将 .Net 项目文件输出路径编辑为与上述相同的 Win32/x64 目录。这将允许DllImport 找到 DLL,因为 DLL/EXE 共享同一个目录。或者,您可以将 DLL 放入可发现的目录或将路径放入 DllImport 中——但是当您使用两个 DLL (32/64) 时,这会出现问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多