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