Thread overview | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 01, 2008 Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
This might be a silly or simple question. I haven't really used shared libraries very much, but have need to now. On Linux with gdc, everything (seems to be) fine. I can make everything work there fine. My problem is with Windows and dmd. Consider the following simple "library": --- module library; import loader; // (the DllMain stuff from D's doc pages.) extern (C) export int foo() { return 42 * loader.bar(); } --- And also consider this "application": --- module loader; import std.c.windows.windows; import std.string, std.stdio; extern (C) alias int function() example_f; void main() { HMODULE m = cast(HMODULE) LoadLibraryA(toStringz("library.dll")); example_f f = cast(example_f) GetProcAddress(m, toStringz("foo")); if (f) writefln("%d", f()); FreeLibrary(m); } extern (C) export int bar() { return 2; } --- This appears to work on Linux. I expected it might work (or there might be some way to coax it to work) on Windows. It seems logical, even not having used the LoadLibrary/etc. stuff before. The library needs to access the caller's functions. It does appear I can make it at least *compile* (but not run) by adding an IMPORTS directive to the .def file of the library, but this clearly is intended for static linking. I'm wanting to load the DLL as a plugin, dynamically. Its name and location might change. Am I making some hopefully obvious and stupid mistake? Please tell me I don't actually have to send pointers to all the api functions to the DLL when calling it. Thanks, -[Unknown] |
February 01, 2008 Re: Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Unknown W. Brackets | "Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:fnu7l0$2p5l$1@digitalmars.com... > This appears to work on Linux. I expected it might work (or there might be some way to coax it to work) on Windows. It seems logical, even not having used the LoadLibrary/etc. stuff before. The library needs to access the caller's functions. > > It does appear I can make it at least *compile* (but not run) by adding an IMPORTS directive to the .def file of the library, but this clearly is intended for static linking. I'm wanting to load the DLL as a plugin, dynamically. Its name and location might change. > > Am I making some hopefully obvious and stupid mistake? Please tell me I don't actually have to send pointers to all the api functions to the DLL when calling it. So, uh, what _exactly_ is the problem? I don't think you ever said.. |
February 01, 2008 Re: Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Sorry, I want to be able to compile and run that. It refuses to do so.
It wants to link against loader.obj, except that defeats the purpose of it being dynamic. I can add IMPORTS to the def, but then it has to be static.
I want to dynamically link, and also call functions from the code that is dynamically linking.
Sorry I was unclear.
-[Unknown]
Jarrett Billingsley wrote:
> "Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:fnu7l0$2p5l$1@digitalmars.com...
>
>> This appears to work on Linux. I expected it might work (or there might be some way to coax it to work) on Windows. It seems logical, even not having used the LoadLibrary/etc. stuff before. The library needs to access the caller's functions.
>>
>> It does appear I can make it at least *compile* (but not run) by adding an IMPORTS directive to the .def file of the library, but this clearly is intended for static linking. I'm wanting to load the DLL as a plugin, dynamically. Its name and location might change.
>>
>> Am I making some hopefully obvious and stupid mistake? Please tell me I don't actually have to send pointers to all the api functions to the DLL when calling it.
>
> So, uh, what _exactly_ is the problem? I don't think you ever said..
>
>
|
February 01, 2008 Re: Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Unknown W. Brackets | Unknown W. Brackets wrote: > Sorry, I want to be able to compile and run that. It refuses to do so. > > It wants to link against loader.obj, except that defeats the purpose of it being dynamic. I can add IMPORTS to the def, but then it has to be static. > > I want to dynamically link, and also call functions from the code that is dynamically linking. > > Sorry I was unclear. > > -[Unknown] > > > Jarrett Billingsley wrote: >> "Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:fnu7l0$2p5l$1@digitalmars.com... >> >>> This appears to work on Linux. I expected it might work (or there might be some way to coax it to work) on Windows. It seems logical, even not having used the LoadLibrary/etc. stuff before. The library needs to access the caller's functions. >>> >>> It does appear I can make it at least *compile* (but not run) by adding an IMPORTS directive to the .def file of the library, but this clearly is intended for static linking. I'm wanting to load the DLL as a plugin, dynamically. Its name and location might change. >>> >>> Am I making some hopefully obvious and stupid mistake? Please tell me I don't actually have to send pointers to all the api functions to the DLL when calling it. >> >> So, uh, what _exactly_ is the problem? I don't think you ever said.. >> If the settings used in your .def file aren't particular the DLL doesnt work as expected. IIRC the def files in the digital mars DLL tutorial diddnt work for me when i first looked at it. maybe try this instead: ----------------------------------- LIBRARY "x.dll" DESCRIPTION 'x.dll' EXETYPE NT CODE PRELOAD DATA PRELOAD |
February 01, 2008 Re: Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Neal Alexander | Thanks. Actually, I have no trouble whatsoever making dlls. I have a problem referencing functions in the program that loaded the DLL.
It turns out (from something I'm read) what I want is simply not possibly with DLLs. I will have to send a pointer table/struct over on to the plugin for this to work the way I want.
Ain't Linux better? Oi.
-[Unknown]
Neal Alexander wrote:
> If the settings used in your .def file aren't particular the DLL doesnt work as expected. IIRC the def files in the digital mars DLL tutorial diddnt work for me when i first looked at it.
>
> maybe try this instead:
> -----------------------------------
> LIBRARY "x.dll"
> DESCRIPTION 'x.dll'
>
> EXETYPE NT
> CODE PRELOAD
> DATA PRELOAD
|
February 01, 2008 Re: Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Unknown W. Brackets | Hm, 1- __declspec(dllimport) int __stdcall foo(); becomes : export extern(Windows) int foo(); so, I would give extern(Windows) instead of extern(C) a try to avoid name mangeling problems. 2- Just guessing : You have module library "DLLMain()" and loader "main()" try to place main() in a seperate file. 3- UNKNOWN WROTE : "I want to dynamically link, and also call functions from the code that is dynamically linking." I can imagine that using callbacks is an interesting option to establish plugings, like : //THE DLL // define the callback function. alias extern(Windows) void function(char* token, size_t siz = 0, bool error =false) DisplayCallBack; export extern(Windows) void ExecuteProcess(DisplayCallBack cb, char* _dir, char* _command, char* _args) { //do someting and call CallBack function defined in Application cb(tok, tok_size) } HTH Bjoern |
February 01, 2008 Re: Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Unknown W. Brackets | "Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:fnuiqt$ags$1@digitalmars.com... > Thanks. Actually, I have no trouble whatsoever making dlls. I have a problem referencing functions in the program that loaded the DLL. You shouldn't need a .def file at all for this program. In fact, you should be able to compile the app the same way you compile any other app. That it loads a dynamic library at runtime means nothing to the compiler/linker. > Ain't Linux better? Oi. DLLs are a pretty awful approximation of SOs, yes. |
February 01, 2008 Re: Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Well, the def being for the library, not for the program loading the library. Otherwise I don't get exports named properly, etc.
-[Unknown]
Jarrett Billingsley wrote:
> "Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:fnuiqt$ags$1@digitalmars.com...
>> Thanks. Actually, I have no trouble whatsoever making dlls. I have a problem referencing functions in the program that loaded the DLL.
>
> You shouldn't need a .def file at all for this program. In fact, you should be able to compile the app the same way you compile any other app. That it loads a dynamic library at runtime means nothing to the compiler/linker.
>
>> Ain't Linux better? Oi.
>
> DLLs are a pretty awful approximation of SOs, yes.
>
>
|
February 01, 2008 Re: Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Unknown W. Brackets | "Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:fnvd2q$229m$1@digitalmars.com... > Well, the def being for the library, not for the program loading the library. Otherwise I don't get exports named properly, etc. In that case, I'd be more interested to see how you're compiling all this code. The code itself looks very simplistic, and I don't see any apparent failure points. |
February 02, 2008 Re: Shared libraries/DLLs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Okay. Example "plugin" example.d: --- module example; extern (C) export int foo(); version (Windows) import utils.windows; extern (C) export int example() { return 42 + foo(); } --- Compiled with: $(DMD) $(DFLAGS_DEBUG) -op -of$(OUTPUT) $(LIBS) $(wildcard utils/*.d) example.d example.def Or: $(GDMD) $(DFLAGS_DEBUG) -op -of$(OUTPUT) $(LIBS) $(wildcard utils/*.d) example.d -fPIC -q,-rdynamic,-shared Plugin linker definition file: --- LIBRARY example.dll DESCRIPTION 'Example' EXETYPE NT SUBSYSTEM WINDOWS 4.0 CODE PRELOAD SHARED DISCARDABLE DATA PRELOAD SINGLE EXPORTS example --- Example host program for Windows, load_test.d: --- module load_test; import std.c.windows.windows; import std.string, std.stdio; extern (C) alias int function() example_f; int main() { HMODULE m = cast(HMODULE) LoadLibraryA(toStringz("example.dll")); example_f f = cast(example_f) GetProcAddress(m, toStringz("example")); if (f) writefln("%d", f()); FreeLibrary(m); return 0; } extern (C) export int foo() { return 43; } --- Quick DllMain file from samples, utils/windows.d: --- module utils.windows; version (Windows): import std.c.windows.windows; extern (C) { void gc_init(); void gc_term(); void _minit(); void _moduleCtor(); void _moduleUnitTests(); HINSTANCE g_hInst; } extern (Windows) BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) { switch (ulReason) { case DLL_PROCESS_ATTACH: gc_init(); // initialize GC _minit(); // initialize module list _moduleCtor(); // run module constructors _moduleUnitTests(); // run module unit tests break; case DLL_PROCESS_DETACH: gc_term(); // shut down GC break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: default: // Multiple threads not supported yet return false; } g_hInst = hInstance; return true; } --- I don't have the Linux loader in front of me but it's almost exactly the same and works just fine (LoadLibraryA => dlopen, GetProcAddress => dlsym, FreeLibrary => dlclose, with some dlerror logic in there.) But as stated, it appears that there's really no "reverse linking" of DLLs. -[Unknown] Jarrett Billingsley wrote: > "Unknown W. Brackets" <unknown@simplemachines.org> wrote in message news:fnvd2q$229m$1@digitalmars.com... >> Well, the def being for the library, not for the program loading the library. Otherwise I don't get exports named properly, etc. > > In that case, I'd be more interested to see how you're compiling all this code. The code itself looks very simplistic, and I don't see any apparent failure points. > > |
Copyright © 1999-2021 by the D Language Foundation