Thread overview
Linking C library (.dll) to D on windows
Jan 25, 2015
Roman
Jan 26, 2015
Mike Parker
Jan 26, 2015
Mike Parker
Jan 26, 2015
Roman
January 25, 2015
Stuff:
1. There are C code module.c and module.h
2. MinGW
3. DMD 2.066.1
4. Window 8.1

module.c:

#include "module.h"
int add(int a, int b) {return a + b;}

module.h:

int add(int,int);

I want to use function "add" from D

so i call

> cc -shared module.c -o module.dll

Then D code

main.d:

import std.stdio;

extern(C)
{
	int add(int a, int b);
}

void main()
{
	writefln("From C Dll %d",add(2,3));
}


So how i should compile with dmd, to get this work?

> dmd main.d -L=module.dll

prints:
OPTLINK (R) for Win32  Release 8.00.15
Copyright (C) Digital Mars 1989-2013  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
OPTLINK : Error 8: Illegal Filename
main,,nul,user32+kernel32/noi=module.dll;

                              ^
--- errorlevel 1

I've tried to found smthing here http://wiki.dlang.org/Compiling_and_linking_with_DMD_on_Windows
but dll tutorial is missing

So does DMD available to link dll files?
January 26, 2015
On 1/26/2015 5:45 AM, Roman wrote:
> Stuff:
> 1. There are C code module.c and module.h
> 2. MinGW
> 3. DMD 2.066.1
> 4. Window 8.1
>
> module.c:
>
> #include "module.h"
> int add(int a, int b) {return a + b;}
>
> module.h:
>
> int add(int,int);
>
> I want to use function "add" from D
>
> so i call
>
>> cc -shared module.c -o module.dll
>
> Then D code
>
> main.d:
>
> import std.stdio;
>
> extern(C)
> {
>      int add(int a, int b);
> }
>
> void main()
> {
>      writefln("From C Dll %d",add(2,3));
> }
>
>
> So how i should compile with dmd, to get this work?
>
>> dmd main.d -L=module.dll
>
> prints:
> OPTLINK (R) for Win32  Release 8.00.15
> Copyright (C) Digital Mars 1989-2013  All rights reserved.
> http://www.digitalmars.com/ctg/optlink.html
> OPTLINK : Error 8: Illegal Filename
> main,,nul,user32+kernel32/noi=module.dll;
>
>                                ^
> --- errorlevel 1
>
> I've tried to found smthing here
> http://wiki.dlang.org/Compiling_and_linking_with_DMD_on_Windows
> but dll tutorial is missing
>
> So does DMD available to link dll files?

Problem #1: linking directly to dlls is not common in the Windows ecosystem. AFAIK, MinGW is the only toolchain that supports that. By default, DMD uses the OPTLINK linker for 32-bit apps and uses the MS linker for 64-bit, neither of which have the ability to link directly with dlls. You need an import library.

Problem #2: OPTLINK only understands the OMF format for object files, whereas MinGW and the MS compiler output COFF. So you have three options for linking with 32-bit DMD:

* Compile with the Digital Mars C/C++ compiler (DMC) and generate an import library along with the dll.
* Compile with another compiler and run implib (part of the free Basic Utilities Package from Digital Mars, downloadable from [1]) on the dll to generate an import library in OMF format.
* Load the DLL dynamically, then you don't need an import library.

extern( C ) alias addptr = int function(int, int);
addptr add;

auto handle = LoadLibrary( "MyLib.dll" );
add = cast( addptr )GetProcAddress( handle, "add" );

Alternatively, you could compile as 64-bit, generate an import library with the DLL when you compile it with MinGW, and link directly with the import lib (the next version of DMD will support COFF for 32-bit). However, I have had trouble attempting to link static MinGW libraries with 64-bit DMD. Some have worked, some haven't. An import library is not the same and I assume it would work, but I've never tried.

Then again, since 64-bit DMD requires the MS toolchain to be installed, another option is to forego MinGW and use the MS compiler instead.
January 26, 2015
On 1/26/2015 11:18 AM, Mike Parker wrote:

> * Compile with another compiler and run implib (part of the free Basic
> Utilities Package from Digital Mars, downloadable from [1]) on the dll
> to generate an import library in OMF format.

[1] http://www.digitalmars.com/download/freecompiler.html

January 26, 2015
On Monday, 26 January 2015 at 02:18:05 UTC, Mike Parker wrote:
> On 1/26/2015 5:45 AM, Roman wrote:
>> Stuff:
>> 1. There are C code module.c and module.h
>> 2. MinGW
>> 3. DMD 2.066.1
>> 4. Window 8.1
>>
>> module.c:
>>
>> #include "module.h"
>> int add(int a, int b) {return a + b;}
>>
>> module.h:
>>
>> int add(int,int);
>>
>> I want to use function "add" from D
>>
>> so i call
>>
>>> cc -shared module.c -o module.dll
>>
>> Then D code
>>
>> main.d:
>>
>> import std.stdio;
>>
>> extern(C)
>> {
>>     int add(int a, int b);
>> }
>>
>> void main()
>> {
>>     writefln("From C Dll %d",add(2,3));
>> }
>>
>>
>> So how i should compile with dmd, to get this work?
>>
>>> dmd main.d -L=module.dll
>>
>> prints:
>> OPTLINK (R) for Win32  Release 8.00.15
>> Copyright (C) Digital Mars 1989-2013  All rights reserved.
>> http://www.digitalmars.com/ctg/optlink.html
>> OPTLINK : Error 8: Illegal Filename
>> main,,nul,user32+kernel32/noi=module.dll;
>>
>>                               ^
>> --- errorlevel 1
>>
>> I've tried to found smthing here
>> http://wiki.dlang.org/Compiling_and_linking_with_DMD_on_Windows
>> but dll tutorial is missing
>>
>> So does DMD available to link dll files?
>
> Problem #1: linking directly to dlls is not common in the Windows ecosystem. AFAIK, MinGW is the only toolchain that supports that. By default, DMD uses the OPTLINK linker for 32-bit apps and uses the MS linker for 64-bit, neither of which have the ability to link directly with dlls. You need an import library.
>
> Problem #2: OPTLINK only understands the OMF format for object files, whereas MinGW and the MS compiler output COFF. So you have three options for linking with 32-bit DMD:
>
> * Compile with the Digital Mars C/C++ compiler (DMC) and generate an import library along with the dll.
> * Compile with another compiler and run implib (part of the free Basic Utilities Package from Digital Mars, downloadable from [1]) on the dll to generate an import library in OMF format.
> * Load the DLL dynamically, then you don't need an import library.
>
> extern( C ) alias addptr = int function(int, int);
> addptr add;
>
> auto handle = LoadLibrary( "MyLib.dll" );
> add = cast( addptr )GetProcAddress( handle, "add" );
>
> Alternatively, you could compile as 64-bit, generate an import library with the DLL when you compile it with MinGW, and link directly with the import lib (the next version of DMD will support COFF for 32-bit). However, I have had trouble attempting to link static MinGW libraries with 64-bit DMD. Some have worked, some haven't. An import library is not the same and I assume it would work, but I've never tried.
>
> Then again, since 64-bit DMD requires the MS toolchain to be installed, another option is to forego MinGW and use the MS compiler instead.

Many thanks Mike,

I've tried second option with MinGW generated dll
> implib /s module.lib module.dll

> dmd main.d module.lib

> main.exe

it prints:
From C Dll 5

So it works !

P.S. I don't know why MinGW generated dll works, and I guess, that in more complicated dll, this can fail