AutoDLL

FoxyBrown via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jul 6 13:34:14 PDT 2017


Here is a solution that will wrap all extern C functions and 
allow one to then map them to a dll.


auto BuildDLLClassFromCHeader(alias modulename, string name)()
{
	import std.traits, std.algorithm, std.meta;
	auto s = "extern (C) class " ~name~"\n{\n\timport ___import = 
"~moduleName!modulename~";\n";
	mixin("import "~moduleName!modulename~";");
	foreach(m; AliasSeq!(__traits(allMembers, modulename)))
	{		
		mixin("alias member = " ~ fullyQualifiedName!(modulename) ~ "." 
~ m ~ ";");		
		static if (is(typeof(member) == function))
			static if (functionLinkage!member != "C")
				continue;
			else
				s ~= "\tpublic static typeof(___import."~__traits(identifier, 
member)~")* "~__traits(identifier, member)~";\n";
	}
	
	return s ~ "}";
}

void DllImport(alias T)(string dllName)
{
	import core.sys.windows.windows, std.conv, std.meta;
	auto dll = LoadLibrary(to!wstring(dllName~"\0").ptr);
	if (dll == null)
		assert(0, "Cannot load DLL `"~dllName~"'");

	foreach(fname; __traits(derivedMembers, T))
	{		
		auto func = GetProcAddress(dll, fname);
		enum s = "auto p = cast(void**)&"~T.stringof~"."~fname~"; *p = 
cast(typeof(p))func;";				
		mixin(s);
	}
}

e.g.,


mixin(BuildDLLClassFromCHeader!(portaudio, "PortAudioDLL")());
DllImport!PortAudioDLL("portaudio_x86.dll");

it generates the following for portaudio.di:

extern (C) class PortAudioDLL
{
	import ___import = portaudio;
	public static typeof(___import.Pa_GetVersion)* Pa_GetVersion;
	public static typeof(___import.Pa_GetVersionText)* 
Pa_GetVersionText;
	public static typeof(___import.Pa_GetErrorText)* Pa_GetErrorText;
	public static typeof(___import.Pa_Initialize)* Pa_Initialize;
	public static typeof(___import.Pa_Terminate)* Pa_Terminate;
	public static typeof(___import.Pa_GetHostApiCount)* 
Pa_GetHostApiCount;
	public static typeof(___import.Pa_GetDefaultHostApi)* 
Pa_GetDefaultHostApi;
	public static typeof(___import.Pa_GetHostApiInfo)* 
Pa_GetHostApiInfo;
	public static typeof(___import.Pa_HostApiTypeIdToHostApiIndex)* 
Pa_HostApiTypeIdToHostApiIndex;
	public static 
typeof(___import.Pa_HostApiDeviceIndexToDeviceIndex)* 
Pa_HostApiDeviceIndexToDeviceIndex;
	public static typeof(___import.Pa_GetLastHostErrorInfo)* 
Pa_GetLastHostErrorInfo;
	public static typeof(___import.Pa_GetDeviceCount)* 
Pa_GetDeviceCount;
	public static typeof(___import.Pa_GetDefaultInputDevice)* 
Pa_GetDefaultInputDevice;
	public static typeof(___import.Pa_GetDefaultOutputDevice)* 
Pa_GetDefaultOutputDevice;
	public static typeof(___import.Pa_GetDeviceInfo)* 
Pa_GetDeviceInfo;
	public static typeof(___import.Pa_IsFormatSupported)* 
Pa_IsFormatSupported;
	public static typeof(___import.Pa_OpenStream)* Pa_OpenStream;
	public static typeof(___import.Pa_OpenDefaultStream)* 
Pa_OpenDefaultStream;
	public static typeof(___import.Pa_CloseStream)* Pa_CloseStream;
	public static typeof(___import.Pa_SetStreamFinishedCallback)* 
Pa_SetStreamFinishedCallback;
	public static typeof(___import.Pa_StartStream)* Pa_StartStream;
	public static typeof(___import.Pa_StopStream)* Pa_StopStream;
	public static typeof(___import.Pa_AbortStream)* Pa_AbortStream;
	public static typeof(___import.Pa_IsStreamStopped)* 
Pa_IsStreamStopped;
	public static typeof(___import.Pa_IsStreamActive)* 
Pa_IsStreamActive;
	public static typeof(___import.Pa_GetStreamInfo)* 
Pa_GetStreamInfo;
	public static typeof(___import.Pa_GetStreamTime)* 
Pa_GetStreamTime;
	public static typeof(___import.Pa_GetStreamCpuLoad)* 
Pa_GetStreamCpuLoad;
	public static typeof(___import.Pa_ReadStream)* Pa_ReadStream;
	public static typeof(___import.Pa_WriteStream)* Pa_WriteStream;
	public static typeof(___import.Pa_GetStreamReadAvailable)* 
Pa_GetStreamReadAvailable;
	public static typeof(___import.Pa_GetStreamWriteAvailable)* 
Pa_GetStreamWriteAvailable;
	public static typeof(___import.Pa_GetSampleSize)* 
Pa_GetSampleSize;
	public static typeof(___import.Pa_Sleep)* Pa_Sleep;
}

and then maps the function pointers to the dll.

Should work for other dlls.



More information about the Digitalmars-d-learn mailing list