www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Import C++ DLL

reply "CrowBar" <john_owen eml.cc> writes:
Please bear with me, I'm very new to C/C++ & D.

I want to Import a function from a DLL made with VC++ express edition into
D.

I have searched the Dprogramming webpages and put together the below code.

The program compiles but does not execute, it returns "Error Access
Violation", (it should display the number 42).


module ModMyDLL;
import std.c.stdio;
import std.c.windows.windows;
import std.stdio;
import std.gc;

//pragma (lib,"MyDLL.lib");

extern(C) alias int function() fnMyDLL_fp;

int main(char[][] args)
{
    HMODULE h;
    h = LoadLibraryA("MyDLL.dll");

    fnMyDLL_fp fnMyDLL;

    fnMyDLL = cast(fnMyDLL_fp) GetProcAddress(h, "fnMyDLL");

    printf("value=%i\n", fnMyDLL());

    return 0;
}
May 18 2007
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
CrowBar wrote:
 Please bear with me, I'm very new to C/C++ & D.
 
 I want to Import a function from a DLL made with VC++ express edition into
 D.
 
[snip]
 
 The program compiles but does not execute, it returns "Error Access
 Violation", (it should display the number 42).
 
 
[snip]
     fnMyDLL = cast(fnMyDLL_fp) GetProcAddress(h, "fnMyDLL");
 
     printf("value=%i\n", fnMyDLL());
[snip] GetProcAddress is probably returning null, you forgot to check for that. It seems to think the function doesn't exist. The most likely cause is name mangling. Try adding an underscore before the first character in the function name. (IIRC that's the mangling for C functions on Windows) If that didn't work, make sure the function is either compiled as C code or marked 'extern "C"' (directly or in an 'extern "C" {}' block) if it's compiled as C++ code.
May 18 2007
parent reply Don Clugston <dac nospam.com.au> writes:
Frits van Bommel wrote:
 CrowBar wrote:
 Please bear with me, I'm very new to C/C++ & D.

 I want to Import a function from a DLL made with VC++ express edition 
 into
 D.
[snip]
 The program compiles but does not execute, it returns "Error Access
 Violation", (it should display the number 42).
[snip]
     fnMyDLL = cast(fnMyDLL_fp) GetProcAddress(h, "fnMyDLL");

     printf("value=%i\n", fnMyDLL());
[snip] GetProcAddress is probably returning null, you forgot to check for that. It seems to think the function doesn't exist. The most likely cause is name mangling. Try adding an underscore before the first character in the function name. (IIRC that's the mangling for C functions on Windows) If that didn't work, make sure the function is either compiled as C code or marked 'extern "C"' (directly or in an 'extern "C" {}' block) if it's compiled as C++ code.
It's incredibly painful to get VC++ to produce extern(C) DLLs. It insists on doing something like: _fnMyDLL 0 essentially ignoring the "extern(C)" declaration. All the __declspec garbage doesn't do much, either. I keep reverting to .DEF files. However, it should be quite simple to make a Microsoft name mangler as as a compile-time function. Hmmm... would make a nice little project. -- You can also use the coffimplib tool (from the DM ftp site) to convert the MS lib to DMD format, and link it statically. Probably easier.
May 19 2007
parent "CrowBar" <john_owen eml.cc> writes:
Thanks, My Prog worked by linking it statically. (Are there any
benefits/drawbacks by using the static/dynamic linking method?)

I changed some settings in VC++ to compile as C.
I then used the 'coffimplib' utility to convert the VC produced 'MyDLL.lib'
to 'MyDLLcoff.lib'.

Below is my revised code;

module ModMyDLL;
import std.c.stdio;
import std.c.windows.windows;
import std.stdio;
import std.gc;

pragma (lib,"MyDLLcoff.lib");
extern(C)
{
 int fnMyDLL();
}

int main(char[][] args)
{
     printf("value=%i\n", fnMyDLL());

     return 0;
}

"Don Clugston" <dac nospam.com.au> wrote in message
news:f2nh7d$18q2$1 digitalmars.com...
 Frits van Bommel wrote:
 CrowBar wrote:
 Please bear with me, I'm very new to C/C++ & D.

 I want to Import a function from a DLL made with VC++ express edition
 into
 D.
[snip]
 The program compiles but does not execute, it returns "Error Access
 Violation", (it should display the number 42).
[snip]
     fnMyDLL = cast(fnMyDLL_fp) GetProcAddress(h, "fnMyDLL");

     printf("value=%i\n", fnMyDLL());
[snip] GetProcAddress is probably returning null, you forgot to check for that. It seems to think the function doesn't exist. The most likely cause is name mangling. Try adding an underscore before the first character in the function name. (IIRC that's the mangling for C functions on Windows) If that didn't work, make sure the function is either compiled as C code or marked 'extern "C"' (directly or in an 'extern "C" {}' block) if it's compiled as C++ code.
It's incredibly painful to get VC++ to produce extern(C) DLLs. It insists on doing something like: _fnMyDLL 0 essentially ignoring the "extern(C)" declaration. All the __declspec garbage doesn't do much, either. I keep reverting to .DEF files. However, it should be quite simple to make a Microsoft name mangler as as a compile-time function. Hmmm... would make a nice little project. -- You can also use the coffimplib tool (from the DM ftp site) to convert the MS lib to DMD format, and link it statically. Probably easier.
May 21 2007
prev sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
CrowBar Wrote:

 Thanks, My Prog worked by linking it statically. (Are there any
 benefits/drawbacks by using the static/dynamic linking method?)
[snip] Quite a few. A quick google search yielded : http://phaseit.net/claird/comp.programming/linking.html , which seems to give a *very* brief summary - Fraser
May 28 2007