简体   繁体   English

在 D 中调用动态库和 static 库中的 C/C++ 函数

[英]Calling C/C++ functions in dynamic and static libraries in D

I'm having trouble wrapping my head around how to interface with C/C++ libraries, both static (.lib/.a) and dynamic (.dll/.so), in D. From what I understand, it's possible to tell the DMD compiler to link with.lib files, and that you can convert.dll files to.lib with the implib tool that Digital Mars provides.我在思考如何与 D 中的 C/C++ 库(static (.lib/.a) 和动态 (.dll/.so) )交互时遇到了麻烦。据我所知,可以告诉DMD 编译器链接.lib 文件,您可以使用 Digital Mars 提供的 implib 工具将.dll 文件转换为.lib。 In addition, I've come across this page , which implies being able to call functions in.dlls by converting C header files to D interface files.另外,我遇到过这个页面,这意味着可以通过将 C header 文件转换为 D 接口文件来调用 in.dlls 中的函数。 Are both of these methods equivalent?这两种方法是否等效? Would these same methods work for Unix library files?这些相同的方法是否适用于 Unix 库文件? Also, how would one reference functions, enums, etc from these libraries, and how would one tell their D compiler to link with these libs (I'm using VisualD, specifically)?此外,如何从这些库中引用函数、枚举等,以及如何告诉他们的 D 编译器与这些库链接(具体来说,我使用的是 VisualD)? If anyone could provide some examples of referencing.lib, .dll, .a, and.so files from D code, I'd be most grateful.如果有人可以提供一些来自 D 代码的引用.lib、.dll、.a 和.so 文件的示例,我将不胜感激。

Note you are dealing with three phases for generating an executable.请注意,您正在处理生成可执行文件的三个阶段。 During compilation you are creating object files (.lib/.a are just archives of object files).在编译期间,您正在创建 object 文件(.lib/.a 只是 object 文件的存档)。 Once these files are created you use a Linker to put all the pieces together.创建这些文件后,您可以使用 Linker 将所有部分放在一起。 When dealing with dynamic libraries (.dll, .so) there is the extra step of loading the library when the program starts/during run-time.在处理动态库(.dll,.so)时,在程序启动/运行时加载库的额外步骤。

During compilation the compiler only needs to be aware of what you are using, it doesn't care if it is implemented.在编译期间,编译器只需要知道你在使用什么,它并不关心它是否被实现。 This is where the D interface files come in and are kind of equivalent to Header Files in this respect.这是 D 接口文件的来源,在这方面与 Header 文件等效。 Enumerations are declared in the D interface file and must also be defined because they only exist at compile time.枚举在 D 接口文件中声明,也必须定义,因为它们仅在编译时存在。 Functions and variables can just be declared with no body.函数和变量可以只声明没有主体。

int myFunction(char* str);

The guide for converting a header file to D is in the page you referenced.将 header 文件转换为 D 的指南在您引用的页面中。 These files can then be passed to the compiler or exist in the Include Path.这些文件然后可以传递给编译器或存在于包含路径中。

When the linker runs is when you'll need the.lib/.a file.当 linker 运行时,您将需要 .lib/.a 文件。 These files can be passed to the compiler which will forward them to the Linker or you can use pragma(lib, "my.lib");这些文件可以传递给编译器,编译器会将它们转发给 Linker 或者您可以使用 pragma(lib, "my.lib"); in your program.在你的程序中。 In both cases the linker must be able to finding at link time (compilation).在这两种情况下,linker 必须能够在链接时找到(编译)。

In Linux I don't believe there is a difference for linking dynamic and static.在 Linux 中,我认为链接动态和 static 没有区别。 In Windows you don't even need the D interface file.在 Windows 中,您甚至不需要 D 接口文件。 Instead you must obtain the function through system calls.相反,您必须通过系统调用获取 function。 I'm really not that familiar with this area, but I suggest Loading Plugins (DLLs) on-the-fly我真的不太熟悉这个领域,但我建议即时加载插件(DLL)

Update: I can't help much with VisualD, but there is D for .NET Programmers .更新:我对 VisualD 帮不上什么忙,但是.NET Programmers 有 D。

There samples in D distribution of how to do this.在D分布中有样本如何做到这一点。

You need to define thunk module like this:您需要像这样定义 thunk 模块:

module harmonia.native.win32;
version(build) { pragma(nolink); }

export int DialogBoxParamA(HINSTANCE hInstance, LPCSTR lpTemplateName,
  HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam);

and include import libs of DLLs where functions like DialogBoxParamA are defined.并包括 DLL 的导入库,其中定义了 DialogBoxParama 等函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM