www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Load D shared library on windows x64

reply Tofu Ninja <joeyemmons yahoo.com> writes:
Do shared libraries work? I am trying to load a D library into a 
D program but Runtime.loadLibrary just returns null for me and I 
am not sure what I am doing wrong.

import std.stdio;
import std.file : exists, getcwd, rename;
import core.thread;
import std.conv : to;
version(tofu_dynamic){
	import core.sys.windows.windows;
	import core.runtime;
	pragma(msg, "Dynamic Link Library");
	HINSTANCE g_hInst;

	export extern (Windows) BOOL DllMain(HINSTANCE hInstance, ULONG 
ulReason, LPVOID pvReserved) {
	    switch (ulReason) {
	        case DLL_PROCESS_ATTACH:
	            writeln("DLL_PROCESS_ATTACH");
	            Runtime.initialize();
	            break;

	        case DLL_PROCESS_DETACH:
	            writeln("DLL_PROCESS_DETACH");
	            Runtime.terminate();
	            break;

	        case DLL_THREAD_ATTACH:
	            writeln("DLL_THREAD_ATTACH");
	            return false;

	        case DLL_THREAD_DETACH:
	            writeln("DLL_THREAD_DETACH");
	            return false;

	        default:
	    }
	    g_hInst = hInstance;
	    return true;
	}

	pragma(mangle, "rti_start") export void rti_start(){
		writeln("rti start :)");
	}

} else {
	void main(string[] args) {
		uint id = 0;

		while(true) {
			if(exists("graph.dll")){
				auto name = "rti." ~ id.to!string ~ ".dll";
				rename("graph.dll", name);
				id++;
		      	     	loadLib(name);
			}
			Thread.sleep(dur!("seconds")(1));
		}
	}

	static void loadLib(string dllName) {
		import core.sys.windows.windows;
		import core.runtime;
		Thread.sleep(dur!("seconds")(1));
		writeln("Start Dynamic Link to ", dllName, "...");
		HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName);
	  	if (h is null) {
	  		writeln("error loading");
	  		return;
	   	}

	 	scope(exit){
			if (!Runtime.unloadLibrary(h))
	 			writeln("error freeing dll");
	   	}

		FARPROC fp = GetProcAddress(h, "rti_start");
		if (fp is null) {
			writeln("error loading symbol rti_start");
			return;
		}
		
		auto fun = cast(void function()) fp;
		fun();
		writeln("End...");
	}
}
Aug 17 2018
parent reply Tofu Ninja <joeyemmons yahoo.com> writes:
Its this part that fails... always returns null

HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName);
if (h is null) {
	writeln("error loading");
	return;
}
Aug 17 2018
parent reply Tofu Ninja <joeyemmons yahoo.com> writes:
On Friday, 17 August 2018 at 20:27:05 UTC, Tofu Ninja wrote:
 Its this part that fails... always returns null

 HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName);
 if (h is null) {
 	writeln("error loading");
 	return;
 }
I there any way to see why Runtime.loadLibrary is failing? It just returns null on error which is not very helpful.
Aug 17 2018
next sibling parent Igor <stojkovic.igor gmail.com> writes:
On Saturday, 18 August 2018 at 00:31:49 UTC, Tofu Ninja wrote:
 On Friday, 17 August 2018 at 20:27:05 UTC, Tofu Ninja wrote:
 Its this part that fails... always returns null

 HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName);
 if (h is null) {
 	writeln("error loading");
 	return;
 }
I there any way to see why Runtime.loadLibrary is failing? It just returns null on error which is not very helpful.
Maybe you can find something useful in how Derelict does it here: https://github.com/DerelictOrg/DerelictUtil/blob/master/source/derelict/util/sharedlib.d
Aug 18 2018
prev sibling parent reply Mike Wey <mike-wey example.com> writes:
On 18-08-18 02:31, Tofu Ninja wrote:
 On Friday, 17 August 2018 at 20:27:05 UTC, Tofu Ninja wrote:
 Its this part that fails... always returns null

 HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName);
 if (h is null) {
     writeln("error loading");
     return;
 }
I there any way to see why Runtime.loadLibrary is failing? It just returns null on error which is not very helpful.
You can probably use: core.sys.windows.winbase.GetLastError -- Mike Wey
Aug 18 2018
parent reply Tofu Ninja <joeyemmons yahoo.com> writes:
On Saturday, 18 August 2018 at 11:27:29 UTC, Mike Wey wrote:
 On 18-08-18 02:31, Tofu Ninja wrote:
 On Friday, 17 August 2018 at 20:27:05 UTC, Tofu Ninja wrote:
 Its this part that fails... always returns null

 HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName);
 if (h is null) {
     writeln("error loading");
     return;
 }
I there any way to see why Runtime.loadLibrary is failing? It just returns null on error which is not very helpful.
You can probably use: core.sys.windows.winbase.GetLastError
That was helpful, error is: ERROR_DLL_INIT_FAILED 1114 (0x45A) A dynamic link library (DLL) initialization routine failed.
Aug 18 2018
parent Tofu Ninja <joeyemmons yahoo.com> writes:
On Saturday, 18 August 2018 at 21:10:55 UTC, Tofu Ninja wrote:
 On Saturday, 18 August 2018 at 11:27:29 UTC, Mike Wey wrote:
 On 18-08-18 02:31, Tofu Ninja wrote:
 On Friday, 17 August 2018 at 20:27:05 UTC, Tofu Ninja wrote:
 Its this part that fails... always returns null

 HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName);
 if (h is null) {
     writeln("error loading");
     return;
 }
I there any way to see why Runtime.loadLibrary is failing? It just returns null on error which is not very helpful.
You can probably use: core.sys.windows.winbase.GetLastError
That was helpful, error is: ERROR_DLL_INIT_FAILED 1114 (0x45A) A dynamic link library (DLL) initialization routine failed.
Thank you this helped lead me to the real error. The problem was here writeln("DLL_PROCESS_ATTACH"); Runtime.initialize(); Cant use writeln before Runtime.initialize
Aug 18 2018