Linking C libraries with DMD

Mike Parker via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jan 21 20:43:52 PST 2016


I've take your example, modified it slightly, compiled the DLL 
with Visual Studio, and got a working executable. Firs up, the C 
file. Here's your original:

> clib.c
> ----------------
> #include <stdio.h>
>
> int some_c_function(int);
>
> int some_c_function(int a) {
> 	printf("Hello, D! from C! %d\n", a);
> 	return a + 20;
> }
>

First, the function prototype is not needed. You only need those 
in header files for other C modules to have access to them. 
Declaring them in the same source file as the function 
implementation serves no purpose.

Second, the Microsoft linker needs to know which functions you 
intend to export from your DLL. In order to tell it, you either 
need to add a __declspec(dllexport) to the functions you plan to 
export, or provide a  module definition file on the command line 
(see [1]). I opted for the former approach. With that, your C 
source file looks like this:

```
#include <stdio.h>

__declspec(dllexport) int some_c_function(int a) {
    printf("Hello, D! from C! %d\n", a);
    return a + 20;
}

```

In the D source file, I opted to remove the pragma in favor of 
passing the import library on the command line:

> extern(C) @nogc nothrow {
> 	int some_c_function(int);
> }
>
> void main()
> {
> 	import std.stdio : writeln;
> 	writeln(some_c_function(10));
> }
>

OK, now create the following file/folder heirarchy:

-vctest
--src
----c/clib.c
----d/dclib.d
--lib
--bin

I have Visual Studio Community 2015 installed. Whichever version 
you have, you should find a folder for it in the Windows start 
menu that provides shortcuts to various command prompts. I opted 
for the one labeled VS2015 x64 Native Tools Command Prompt. You 
might select the 32-bit (x86) version instead. Open one of them, 
navigate to the vctest directory, and execute the following 
command line:

cl /D_USRDLL /D_WINDLL src\c\clib.c /LD /Felib\clib.lib /link

Note the backslashes in src\c\clib.c and lib\clib.lib. You'll 
likely see an error with forward slashes, unless you put the 
paths in quotes (see [2] for compiler options). This should 
create both clib.dll and the import library clib.lib in the lib 
directory. Next, copy the dll to the bin directory:

copy lib\clib.dll bin

Now, either in the same command prompt or a separate one where 
DMD is on the path (depending on your configuration), execute the 
following:

dmd -m64 src/d/dclib.d lib/clib.lib -ofbin/dclib.exe

Replace -m64 with -m32mscoff if you used the 32-bit toolchain 
instead of the 64-bit.

Following these steps, I produced a working executable that 
output the following:

Hello, D! from C! 10
30


[1] https://msdn.microsoft.com/en-us/library/34c30xs1.aspx
[2] https://msdn.microsoft.com/en-us/library/19z1t1wy.aspx


More information about the Digitalmars-d-learn mailing list