构建 .NET 包装器是否需要源代码?

Is source code required to build a .NET wrapper?

是否需要 C++ 源代码来构建 .NET 包装器或静态库 *.lib 文件就足够了?

我们计划使用 SWIG

谢谢。

w.r.t。你的问题专门询问静态库 *.lib:

Is C++ source code required to build a .NET wrapper or static libraries *.lib files are just enough?

我怀疑您是否真的打算包装静态库:静态链接库通常不可再分发或可移植(例如,闭源静态库的作者需要在每次出现新的受支持的编译器时构建它们,例如,您不能将 GCC 库与 VisualC++ 2017 一起使用,并且 x64 VisualC++ 2017 库将与 x86 VisualC++ 2015 项目不兼容) - 即使您将 *.lib 加载到进程的内存中,并且跳转到 lib 映像内的已知函数地址,它会立即中断,因为静态库的代码将引用某些内存地址(例如字符串常量)which aren't yet relocated - 你会得到一个段错误(或 "Access violation" on Windows) 如果你 幸运 会崩溃(否则,它肯定会在被发现之前破坏你的进程的内存 space)。

P/Invoke in .NET Framework 和 .NET on Windows(即使用 [DllImport])仅支持 DLL(动态链接库),不支持静态链接库。

如果本机代码作为 COM 对象可用,或者可以通过 OLE、WMIC、ADSI 等平台功能访问(假设您的代码的进程与本机的 ISA 相同),您也可以调用本机代码您要调用的代码,因为它仍将加载到您的进程中,这就是为什么您不能使用 64 位 Office Excel 打开只有 32 位 OLE-DB 或 ODBC 驱动程序可用的数据库的原因).

当一个库作为 *.lib 可用时,您需要首先创建自己的本地主机 - 一个简单的 C/C++ Win32 (PE) EXE 或 DLL,它可以重新导出所有*.lib 中的有用函数就足够了 - 因为这些导出可以通过 C#/.NET 导入。

但总的来说:

  • 如果要将 COM 对象导出到 .NET,则不需要源代码文件(*.c*.cpp)或头文件(*.h*.hpp),只有编译器会为你生成的 IDL 文件或 *.tlb (Type-lib)。
  • 如果您的本机代码也可通过其他平台功能使用,例如 OLE、ActiveX、COM 自动化 (IDispatch)、ODBC、OLE-DB、ADSI、WMI 等,那么您就不会使用 [ DllImport],这些平台都提供标准接口(如 ODBC 和 OLE-DB)
  • 但一般来说,不需要 - 您不需要源代码(即 *.c*.h 文件)来围绕从本机 DLL 导出的本机代码创建 .NET 包装器,并且使用 [DllImport] 导入到 .NET 中。
    • 但是除了了解编译器设置(用于找出诸如调用约定、参数编组信息等)和 PE 检查器(以验证导出的函数至少存在于您要加载的 DLL 中)。
  • 如果您正在为 AnyCPU 编译 C#/.NET 代码,请不要忘记确保为所有功能提供 x86 和 x64 本机 DLL(提示:Using a 32bit or 64bit dll in C# DllImport