Thread overview
Import C++ DLL
May 18, 2007
CrowBar
May 18, 2007
Frits van Bommel
May 19, 2007
Don Clugston
May 21, 2007
CrowBar
May 18, 2007
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
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 19, 2007
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
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.