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

Posted

技术标签:

【中文标题】构建 .NET 包装器是不是需要源代码?【英文标题】:Is source code required to build a .NET wrapper?构建 .NET 包装器是否需要源代码? 【发布时间】:2019-10-30 07:27:58 【问题描述】:

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

我们计划使用SWIG。

谢谢。

【问题讨论】:

你需要库和头文件 看看this 我很困惑你为什么要问 - SWIG 似乎完全符合你的要求 - 或者你的意思是你打算以某种方式将 C# 程序静态链接到 SWIG 本身?这……很奇怪。 如果没有 .h 文件,您将无法使用 SWIG,当然您拥有它们。小心一点,你必须学习两件事,而不仅仅是 C++/CLI,我们可以告诉你,从你标记问题的方式来看,你并没有跟上这方面的速度。如果非托管接口相对简单且稳定,那么您根本不需要 SWIG。如果您只有一个 .lib 文件,则几乎暗示了稳定。并且要小心那个静态 .lib 文件,它通常必须使用您正在使用的相同工具集版本来构建以避免麻烦。 【参考方案1】:

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

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

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

.NET Framework 中的 P/Invoke 和 Windows 上的 .NET(即使用 [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 包装器,并使用 @ 导入到 .NET 987654336@。 但是除了了解编译器设置(用于查找调用约定、参数封送信息等)之外,您还需要 C/C++ 项目中的头文件 (*.h) ) 和 PE 检查器(验证导出的函数至少存在于您要加载的 DLL 中)。 如果要为AnyCPU 编译 C#/.NET 代码,请不要忘记确保为所有功能提供 x86 和 x64 本机 DLL(提示:Using a 32bit or 64bit dll in C# DllImport)

【讨论】:

以上是关于构建 .NET 包装器是不是需要源代码?的主要内容,如果未能解决你的问题,请参考以下文章

authorize.net C# 包装器/库

OpenCL:如何使用 C++ 包装器检查构建错误

从 .NET 代码中销毁非托管对象

我是不是需要(或应该)将我所有的 Vue 组件包装在一个包装器组件中?

通过 CLI 包装器在非托管 C++ 中使用 C#.NET Winform - 需要线程?

如何将 C++ dll 静态链接到 .NET 库(将 c++ dll 构建到网络包装器 dll 以获取一个 dll)