我在我的项目中使用了一些静态编译的库 (.lib),这些库是用 C++ 编写的,并在 Windows 和 Linux 上构建。在我的项目的这些库的入口点,我只使用静态库套件中“主”库中的一两个函数(但我确信这些函数调用了套件中其他库中的许多其他函数) .

理想情况下,我希望拥有一套动态链接库 (DLL),它环绕静态库套件中的每个库;我读过/听说在 Windows(例如 Visual Studio 2005/2008/2010)上执行此操作的方法是“创建一个包装 DLL”,其中包含一些调用底层静态库函数的公开函数。如果有人能给我一些详细的分步说明,包括可能的一些片段,关于如何在 MS Visual Studio 2005/2008/2010 中执行此操作,我将不胜感激。我相信你们中的一些人可能已经每天都这样做了;非常感谢您的经验。

编辑:

为了像我这样的其他人的利益,我发布了我发现的第一个“有用”链接:
http://tom-shelton.net/index.php/2008/12/11/creating-a-managed-wrapper-for-a-lib-file/

最佳答案

“将库转换为另一种库类型”似乎很容易,但事实并非如此。没有直接的分步方法可以做到这一点,因为 C++ 和 DLL 根本不能很好地协同工作,并且您的代码需要进行调整以支持 DLL 接口(interface)。

描述问题的简洁方法是:

  • .lib 的接口(interface)是 C++
  • .dll 的接口(interface)是 C

  • 因此,DLL 的接口(interface)根本不支持 C++,您需要聪明地使其工作 - 这就是现有答案模棱两可的原因。

    一种标准方法是通过 COM,这意味着为库构建一个完整的 COM 包装器,包括类工厂、接口(interface)、对象,并使用 BSTR 而不是 std::string 。我猜是不实用的。

    另一种解决方案是为您的 C++ 库创建一个 C 接口(interface),该接口(interface)是 DLL 安全的。这意味着基本上创建一个 winapi 风格的界面,这又可能不切实际或完全违背了使用你的库的目的。这就是@David Heffernan 所建议的。但是他没有解决的是您必须如何将代码更改为与 DLL 兼容。

    一个重要但微妙的问题是您不能跨 DLL 边界传递任何模板化的 C++ 对象。这意味着将 std::string 传入或传出 DLL 函数被认为是不安全的。每个二进制文件都有自己的 std::string 代码拷贝,并且不能保证它们会碰巧相互配合。每个二进制文件(可能)也有自己的 CRT 拷贝,您将通过操作另一个模块的对象来弄乱一个模块的内部状态。

    编辑 :您可以使用 __declspec(dllexport) 在 MSVC 中导出 C++ 对象并使用 __declspec(dllimport) 导入它们。但是这有很多限制和导致问题的微妙之处。基本上,这是让编译器为导出的类或函数创建廉价的 C 样式接口(interface)的快捷方式。问题是它不会警告您发生了多少不安全的事情。重申:
  • 如果有任何跨越 DLL 边界的模板化符号,则它是不安全的(例如 std::*)。
  • 任何具有 CRT 管理状态的对象都不应跨越 DLL 边界(例如 FILE*)。
  • 关于C++ 包装 DLL 到静态 LIB,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7247394/

    10-11 22:57
    查看更多