【问题标题】:Calling C/C++ functions in dynamic and static libraries in D在 D 中调用动态和静态库中的 C/C++ 函数
【发布时间】:2011-05-31 18:20:16
【问题描述】:

我在思考如何与 D 中的静态 (.lib/.a) 和动态 (.dll/.so) 的 C/C++ 库进行交互时遇到了麻烦。据我了解,这是可能的告诉 DMD 编译器链接 .lib 文件,并且您可以使用 Digital Mars 提供的 implib 工具将 .dll 文件转换为 .lib。另外,我遇​​到过this page,这意味着可以通过将C 头文件转换为D 接口文件来调用.dlls 中的函数。这两种方法是否等效?这些相同的方法是否适用于 Unix 库文件?另外,如何从这些库中引用函数、枚举等,以及如何告诉他们的 D 编译器与这些库链接(具体来说,我使用的是 VisualD)?如果有人能提供一些从 D 代码中引用 .lib、.dll、.a 和 .so 文件的示例,我将不胜感激。

【问题讨论】:

    标签: c++ c d


    【解决方案1】:

    请注意,您正在处理生成可执行文件的三个阶段。在编译期间,您正在创建目标文件(.lib/.a 只是目标文件的存档)。创建这些文件后,您可以使用链接器将所有部分放在一起。在处理动态库(.dll、.so)时,需要在程序启动/运行时加载库的额外步骤。

    在编译期间,编译器只需要知道你在使用什么,它并不关心它是否被实现。这就是 D 接口文件的用武之地,在这方面与头文件相当。枚举在 D 接口文件中声明,也必须定义,因为它们仅在编译时存在。函数和变量可以只声明没有主体。

    int myFunction(char* str);
    

    将头文件转换为 D 的指南在您引用的页面中。然后这些文件可以传递给编译器或存在于包含路径中。

    当链接器运行时,您将需要 .lib/.a 文件。这些文件可以传递给编译器,编译器会将它们转发给链接器,或者您可以使用 pragma(lib, "my.lib");在你的程序中。在这两种情况下,链接器都必须能够在链接时找到(编译)。

    在 Linux 中,我认为链接动态和静态没有区别。在 Windows 中,您甚至不需要 D 接口文件。相反,您必须通过系统调用获取该函数。我对这个领域真的不是很熟悉,但我建议Loading Plugins (DLLs) on-the-fly

    更新:我对 VisualD 帮不上什么忙,但有 D for .NET Programmers

    【讨论】:

    • 我可以使用编译指示从我的代码中链接到 *.lib 文件,但可执行文件似乎仍然需要 *.dll 文件。 IIRC,使用静态库不应该需要任何外部依赖,不是吗?
    • 静态文件本身依赖于 .dll。在这种情况下,它们只是为您完成所有动态加载。
    【解决方案2】:

    D中有样本分布如何做到这一点。

    您需要像这样定义 thunk 模块:

    module harmonia.native.win32;
    version(build) { pragma(nolink); }
    
    export int DialogBoxParamA(HINSTANCE hInstance, LPCSTR lpTemplateName,
      HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam);
    

    并包含 DLL 的导入库,其中定义了 DialogBoxParama 等函数。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    相关资源
    最近更新 更多