DLLs and headaches
Unknown W. Brackets
unknown at simplemachines.org
Mon May 4 01:07:16 PDT 2009
This is kinda complicated, hopefully someone will still read it and try it.
DLLs typically don't have access to the host process. Sometimes, when
creating plugins, such access may be desirable. The typical solution is
to have the host and plugins both load a secondary DLL.
I've tried to replicate this with D. I have a stub program, a "primary"
dll, and a "plugin" dll.
Although the solution in itself does work, I'm having a lot of problems
and they seem related to D. But, maybe I'm just doing it all wrong?
If I import std.stdio in a DLL, it won't compile. Period. Otherwise,
the primary DLL never finishes - it just dies when it frees the plugin
library.
There are a bunch of files, unfortunately. Listing below:
--- test.d ---
import std.c.stdio;
import primary;
extern (C)
void* gc_getProxy();
// Just a stub to load the primary code.
int main()
{
printf("Entering main().\n");
primary_init(gc_getProxy());
int ret = primary_main();
primary_terminate();
printf("Exiting main().\n");
return ret;
}
---------
--- plugin.d ---
import core.runtime;
import std.c.stdio;
import std.c.windows.windows;
import primary;
extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
{
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
printf("DLL_PROCESS_ATTACH -> plugin\n");
Runtime.initialize();
break;
case DLL_PROCESS_DETACH:
printf("DLL_PROCESS_DETACH -> plugin\n");
Runtime.terminate();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
return false;
}
return true;
}
// This is just here to load a plugin and export anything.
export void dummy()
{
}
---------
--- plugin.def ---
LIBRARY plugin
DESCRIPTION 'Plugin Example'
EXETYPE NT
CODE PRELOAD DISCARDABLE
DATA PRELOAD SINGLE
---------
--- primary.d ---
import std.c.windows.windows;
import core.runtime;
import std.c.stdio;
// SKIP_RUNTIME uses Windows instead of Runtime.*, makes no difference.
// FAIL2 shows that it won't even compile with std.stdio.
version (FAIL2)
import std.stdio;
extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
{
switch (ulReason)
{
case DLL_PROCESS_ATTACH:
printf("DLL_PROCESS_ATTACH -> primary\n");
Runtime.initialize();
break;
case DLL_PROCESS_DETACH:
printf("DLL_PROCESS_DETACH -> primary\n");
Runtime.terminate();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
return false;
}
return true;
}
extern (C)
{
void gc_setProxy(void* p);
void gc_clrProxy();
}
export void primary_init(void* gc)
{
printf("primary_init()\n");
gc_setProxy(gc);
}
export void primary_terminate()
{
printf("primary_terminate()\n");
gc_clrProxy();
}
export int primary_main()
{
HMODULE h;
FARPROC fp;
bool unloaded;
printf("Start Dynamic Link...\n");
version (SKIP_RUNTIME)
h = LoadLibraryA("plugin.dll");
else
h = cast(HMODULE) Runtime.loadLibrary("plugin.dll");
if (h is null)
{
printf("error loading plugin.dll\n");
return 1;
}
version (FAIL2)
writefln("hi");
version (SKIP_RUNTIME)
unloaded = FreeLibrary(h) != 0;
else
unloaded = Runtime.unloadLibrary(h);
if (!unloaded)
{ printf("error freeing plugin.dll\n");
return 1;
}
printf("End...\n");
return 0;
}
---------
--- primary.def ---
LIBRARY primary
DESCRIPTION 'Primary Program'
EXETYPE NT
CODE PRELOAD DISCARDABLE
DATA PRELOAD SINGLE
---------
--- compilation ---
echo === Compile the primary DLL.
dmd primary.d primary.def -g -L/map
implib /noi /system primary.lib primary.dll
echo === Compile the example plugin.
dmd plugin.d plugin.def primary.lib -g -L/map
echo === Compile the stub.
dmd test.d primary.lib -g
---------
Anyone know anything?
-[Unknown]
More information about the Digitalmars-d-learn
mailing list