digitalmars.D - How to call a dll function from D?
- snowflake (6/6) May 02 2004 I've read through the docs but I can't seem to work out how to declare a
- firefly fssc.demon.co.uk (5/11) May 02 2004 After I posted this message I noticed that loadlibrary and getprocaddres...
- Eric Anderton (22/25) May 03 2004 It just so happens that I was working on the very same thing yesterday. ...
- firefly fssc.demon.co.uk (5/10) May 03 2004 Perfect, thanks! I just sent another post but ignore it, your email answ...
- firefly fssc.demon.co.uk (7/20) May 03 2004 I was a bit premature in my reply, I don't understand your use of the al...
- Eric Anderton (9/14) May 03 2004 Ack.
- firefly fssc.demon.co.uk (5/21) May 03 2004 Thanks Eric, the new syntax works for me. The only issue now I have is
- Eric Anderton (22/25) May 03 2004 This is just a shot in the dark, but have you tried prefixing the handle
- firefly fssc.demon.co.uk (9/34) May 04 2004 Thanks again for the help, you're the only one who has given me sensible
- Eric Anderton (8/13) May 04 2004 So I'm not the only one sifting through Walter's code! ::chuckle:: Late...
- Matthew (13/19) May 02 2004 I've written the std.loader module, which will hopefully appear in the n...
- firefly fssc.demon.co.uk (7/29) May 03 2004 Thanks for the information. The question now is how do I declare a funct...
- Achilleas Margaritis (18/24) May 04 2004 It seems that you want to link with a specific DLL in compile time, inst...
I've read through the docs but I can't seem to work out how to declare a function that can to be loaded from a specific dll. The calling convention is cdecl. Is there a sort of equivalent loadlibrary() machanism? I tried to link the function via a lib file but the linker says "Error 43: Not a Valid Library File", even though the file is used by other apps on the computer. HMS
May 02 2004
After I posted this message I noticed that loadlibrary and getprocaddress are available from the windows module. Anyone got an example showing how to use the GetProcAddress function in D? HMS In article <c74emg$fe2$1 digitaldaemon.com>, snowflake says...I've read through the docs but I can't seem to work out how to declare a function that can to be loaded from a specific dll. The calling convention is cdecl. Is there a sort of equivalent loadlibrary() machanism? I tried to link the function via a lib file but the linker says "Error 43: Not a Valid Library File", even though the file is used by other apps on the computer. HMS
May 02 2004
After I posted this message I noticed that loadlibrary and getprocaddress are available from the windows module. Anyone got an example showing how to use the GetProcAddress function in D?It just so happens that I was working on the very same thing yesterday. :) GetProcAddress returns the address of an export on the dll. You can cast this value to a function handle (see below) or a variable address if desired. More explicit information can be found at MDSN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp The quick and dirty D version goes something like this: import std.c.windows.windows; alias (*HelloWorldHandle)(/*put your handle parameters here*/); void LoadLibraryExample(string libraryFileName){ HANDLE hLibrary; //make sure you have a trailing \0 when you cast to a c-style string! hLibrary = LoadLibraryA((char*)(libraryFileName ~ "\0")); if(hLibrary){ HelloWorldHandle helloWorld = (HelloWorldHandle)GetProcAddress(hLibrary,(char*)("HelloWorld\0")); if(!helloWorld) throw new Exception("Failure to load HelloWorld handle."); } helloWorld(/*put your handle arguments here*/); FreeLibrary(hLibrary); } else throw new Exception("Failure to load library: " ~ libraryFileName); }
May 03 2004
Perfect, thanks! I just sent another post but ignore it, your email answers my question. Herbert Sauro In article <c75it6$26gf$1 digitaldaemon.com>, Eric Anderton says...etcAfter I posted this message I noticed that loadlibrary and getprocaddress are available from the windows module. Anyone got an example showing how to use the GetProcAddress function in D?It just so happens that I was working on the very same thing yesterday. :) GetProcAddress returns the address of an export on the dll. You can cast this
May 03 2004
I was a bit premature in my reply, I don't understand your use of the alias keyword, I thought alias tokk two parts, the thingk to alias and the alias name, but in your example you only have one of these, i.e alias (*HelloWorld)(/* args got here*/); I don't understnd how you are declaring the function pointer type. Herbert Sauro In article <c76119$2sbv$1 digitaldaemon.com>, firefly fssc.demon.co.uk says...Perfect, thanks! I just sent another post but ignore it, your email answers my question. Herbert Sauro In article <c75it6$26gf$1 digitaldaemon.com>, Eric Anderton says...etcAfter I posted this message I noticed that loadlibrary and getprocaddress are available from the windows module. Anyone got an example showing how to use the GetProcAddress function in D?It just so happens that I was working on the very same thing yesterday. :) GetProcAddress returns the address of an export on the dll. You can cast this
May 03 2004
I was a bit premature in my reply, I don't understand your use of the alias keyword, I thought alias tokk two parts, the thingk to alias and the alias name, but in your example you only have one of these, i.e alias (*HelloWorld)(/* args got here*/); I don't understnd how you are declaring the function pointer type.Ack. Leave it to me to post a suggestion without compiling it first, as I didn't include the return type. It should read: alias void (*HelloWorldHandle)(/*args*/); Now, this should look like the good-old C/C++ style for a function pointer. D also provides a more succinct way of doing this (and less misunderstood syntax IMO). function(/*args*/) HelloWorldHandle; //Same thing, but no 'alias' required Hope this clears things up.
May 03 2004
Thanks Eric, the new syntax works for me. The only issue now I have is specifying the calling convention, I need to specify cdecl. I'm currently getting an access violation which I assume is due to a bad calling mechanism. Herbert In article <c768it$67u$1 digitaldaemon.com>, Eric Anderton says...I was a bit premature in my reply, I don't understand your use of the alias keyword, I thought alias tokk two parts, the thingk to alias and the alias name, but in your example you only have one of these, i.e alias (*HelloWorld)(/* args got here*/); I don't understnd how you are declaring the function pointer type.Ack. Leave it to me to post a suggestion without compiling it first, as I didn't include the return type. It should read: alias void (*HelloWorldHandle)(/*args*/); Now, this should look like the good-old C/C++ style for a function pointer. D also provides a more succinct way of doing this (and less misunderstood syntax IMO). function(/*args*/) HelloWorldHandle; //Same thing, but no 'alias' required Hope this clears things up.
May 03 2004
Thanks Eric, the new syntax works for me. The only issue now I have is specifying the calling convention, I need to specify cdecl. I'm currently getting an access violation which I assume is due to a bad calling mechanism.This is just a shot in the dark, but have you tried prefixing the handle definition with "extern(C)"? extern(C) function(int foo) bar; // maybe this will create the right call type? After looking over Walter's D documentation again, I think the "extern" statement gets double-duty when compared to C/C++. Where in C we use "extern" to mean "declared later/elsewhere", D uses it for that as well as the calling convention. Add to that the fact that DMD makes multiple passes on any given source file, and it really shifts the meaning more towards being a call-type declaration. Again, no D compiler in sight until I get home... so here goes nothing, right? - Eric from: http://www.digitalmars.com/d/htomodule.html __cdecl, __pascal, __stdcall int __cdecl x; int __cdecl foo(int a); int __pascal bar(int b); int __stdcall abc(int c); become: extern (C) int x; extern (C) int foo(int a); extern (Pascal) int bar(int b); extern (Windows) int abc(int c);
May 03 2004
Thanks again for the help, you're the only one who has given me sensible responses. Tonight I had an idea (don't know why I didn't think of it before), I searched the dmd directory for GetProcAddress, and to my surprise I found a sample file which gave an example. You were actually very close, the only thing that was off was the alias declaration, it should have been: extern (C) alias void (*ptr)(/* args */); This is not particularly clear from the documentation. Herbert In article <c76bn6$at5$1 digitaldaemon.com>, Eric Anderton says...Thanks Eric, the new syntax works for me. The only issue now I have is specifying the calling convention, I need to specify cdecl. I'm currently getting an access violation which I assume is due to a bad calling mechanism.This is just a shot in the dark, but have you tried prefixing the handle definition with "extern(C)"? extern(C) function(int foo) bar; // maybe this will create the right call type? After looking over Walter's D documentation again, I think the "extern" statement gets double-duty when compared to C/C++. Where in C we use "extern" to mean "declared later/elsewhere", D uses it for that as well as the calling convention. Add to that the fact that DMD makes multiple passes on any given source file, and it really shifts the meaning more towards being a call-type declaration. Again, no D compiler in sight until I get home... so here goes nothing, right? - Eric from: http://www.digitalmars.com/d/htomodule.html __cdecl, __pascal, __stdcall int __cdecl x; int __cdecl foo(int a); int __pascal bar(int b); int __stdcall abc(int c); become: extern (C) int x; extern (C) int foo(int a); extern (Pascal) int bar(int b); extern (Windows) int abc(int c);
May 04 2004
Thanks again for the help, you're the only one who has given me sensible responses.You're quite welcome. Anything to help a fellow developer. Be sure to let us (the NG) know how the project pans out.Tonight I had an idea (don't know why I didn't think of it before), I searched the dmd directory for GetProcAddress, and to my surprise I found a sample file which gave an example.So I'm not the only one sifting through Walter's code! ::chuckle:: Lately, I've taken to pulling apart Phobos to learn more about the platform. IMO, this is the best way (at least for now) to learn how to do "undocumented" things with the D platform. And as far as source goes, its a pretty good read. ; - Eric
May 04 2004
I've written the std.loader module, which will hopefully appear in the next release of the compiler/library. That doesn't help you now, though, does it? You can just declare extern(Windows) { void *LoadLibraryA(char *libName); int FreeLibrary(void *hLib); void *GetProcAddress(void *hModule, char *procName); } and proceed with them "snowflake" <snowflake_member pathlink.com> wrote in message news:c74emg$fe2$1 digitaldaemon.com...I've read through the docs but I can't seem to work out how to declare a function that can to be loaded from a specific dll. The calling convention is cdecl. Is there a sort of equivalent loadlibrary() machanism? I tried to link the function via a lib file but the linker says "Error 43: Not a Valid Library File", even though the file is used by other apps on the computer. HMS
May 02 2004
Thanks for the information. The question now is how do I declare a function pointer for the dll method I want to load. In C I would use: typedef int (*ADDITIONFUNCTION)(int a,int b); ADDITIONFUNCTION addFunction; addFunction = (ADDITIONFUNCTION) GetProcAddress(hDll, "fnDemoDll"); Herbert Sauro In article <c74g00$h1b$1 digitaldaemon.com>, Matthew says...I've written the std.loader module, which will hopefully appear in the next release of the compiler/library. That doesn't help you now, though, does it? You can just declare extern(Windows) { void *LoadLibraryA(char *libName); int FreeLibrary(void *hLib); void *GetProcAddress(void *hModule, char *procName); } and proceed with them "snowflake" <snowflake_member pathlink.com> wrote in message news:c74emg$fe2$1 digitaldaemon.com...I've read through the docs but I can't seem to work out how to declare a function that can to be loaded from a specific dll. The calling convention is cdecl. Is there a sort of equivalent loadlibrary() machanism? I tried to link the function via a lib file but the linker says "Error 43: Not a Valid Library File", even though the file is used by other apps on the computer. HMS
May 03 2004
In article <c74emg$fe2$1 digitaldaemon.com>, snowflake says...I've read through the docs but I can't seem to work out how to declare a function that can to be loaded from a specific dll. The calling convention is cdecl. Is there a sort of equivalent loadlibrary() machanism? I tried to link the function via a lib file but the linker says "Error 43: Not a Valid Library File", even though the file is used by other apps on the computer. HMSIt seems that you want to link with a specific DLL in compile time, instead of run-time, right ? Ok, here it is: DigitalMars has a tool named 'implib.exe' which is part of the DigitalMars C/C++ compiler package which takes a DLL as an argument and produces a .lib file which can be used with the DM linker. For example, let's say you have foo.dll which contains the function int foo(int) You do the following steps: 1) execute: implib foo.dll foo.lib 2) Link with foo.lib. 3) in your program, you must have: extern(C) int foo(int); 4) use function 'foo' normally. This is how I used the Allegro DLL with D.
May 04 2004