www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Linking C library (.dll) to D on windows

reply "Roman" <shamyan.roman gmail.com> writes:
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?
Jan 25 2015
parent reply Mike Parker <aldacron gmail.com> writes:
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.
Jan 25 2015
next sibling parent Mike Parker <aldacron gmail.com> writes:
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
Jan 25 2015
prev sibling parent "Roman" <shamyan.roman gmail.com> writes:
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
Jan 26 2015