I know that you can do it either way with C++ and D but the fact that other popular wrappers for D are distributed and used in this way i would like to provide the most common method as well.
I believe many of my problems come from my use of templating with D in order to call the DarkGDK functions.
My idea was to have a template that is given the return type, loadPtr, noSafeCall etc and the arguments that you pass to the loaded dll function and that way each wrapped function would be much smaller using this template.
template GDKfunctionTemplate(R, bool loadPtr, bool noSafeCall, string dllName, string exportName, T ...){
R GDKfunctionTemplate(T GDKargs){
static if (!is(R == void))
R result = R.init;
alias R function(T) GDKfunction_fp;
GDKfunction_fp GDKfunction;
static if (loadPtr && noSafeCall){
FARPROC fp;
Lib = GetModuleHandleA(dllName);
fp = GetProcAddress(Lib, exportName);
if (fp is null){
static if (is(R == void))
return;
else
return R.init;
}
GDKfunction = cast(GDKfunction_fp) fp;
result = GDKfunction(GDKargs[0], GDKargs[1].toStringz, GDKargs[2].toStringz);
} else static if (noSafeCall && !loadPtr){
if (!GDKfunction && !GDKLoadPtr(cast(int*)&GDKfunction, dllName, exportName) )
static if (!is(R == void))
return result;
else
return;
static if (!is(R == void))
result = GDKfunction(GDKargs);
else
GDKfunction(GDKargs);
} else {
if (GDKWaitFunction()){
if (!GDKfunction && !GDKLoadPtr(cast(int*)&GDKfunction, dllName, exportName) )
static if (!is(R == void))
return result;
else
return;
static if (!is(R == void))
result = GDKfunction(GDKargs);
else
GDKfunction(GDKargs);
GDKCleanupFunctionCall();
}
}
static if (!is(R == void))
return result;
else
return;
}
}
And for an example usage here are two:
int GDKLoadPtr(int* *procAddress, string library, string procName){
int result = GDKfunctionTemplate!(int, false, false, "darkgdk.dll", "GDKDLL_LoadPtr"
, int*, immutable(char)*, immutable(char)*)(
*procAddress, library.toStringz, procName.toStringz);
return cast(int)result;
}
void dbSetD3DDeviceCallback(int* *procAddress, int callbackType){
GDKfunctionTemplate!(void, false, false, "gdkcallback.dll", "SetCallback"
, int*, int)(
*procAddress, callbackType);
}
Note those two functions are made by the current, not complete or ready, version of gdk_dlang.dll that buildlibs uses so there may be issues in them.
The idea here was to reduce the amount of code in each wrapped function (and thus the language plugin requires less complexity to write a function) by using a template. Because i am having an issue and finding it hard to debug i am re-writing the language plugin to not use a templates now, might have a version done tonight or tomorrow for testing so long as i can get my simpleWindow.d to work.
While i know things can be made to work as they are i believe if your going to write a wrapper for another language you should provide that wrapper in a way that is common to that language.
Either in the wrapper code as you have done with oop support in the .net wrapper, or in the use of the wrapper like i mentioned that it seems the .lib with accompanying .di files are the standard or common way to do so in D.
I swear to the programmers bible that I shall not harm the FPS.