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