Thread overview
Load D shared library on windows x64
Aug 17, 2018
Tofu Ninja
Aug 17, 2018
Tofu Ninja
Aug 18, 2018
Tofu Ninja
Aug 18, 2018
Igor
Aug 18, 2018
Mike Wey
Aug 18, 2018
Tofu Ninja
Aug 18, 2018
Tofu Ninja
August 17, 2018
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...");
	}
}

August 17, 2018
Its this part that fails... always returns null

HMODULE h = cast(HMODULE) Runtime.loadLibrary(dllName);
if (h is null) {
	writeln("error loading");
	return;
}


August 18, 2018
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.
August 18, 2018
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
August 18, 2018
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
August 18, 2018
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.
August 18, 2018
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