Runtime Dynamic Linking
John C
johnch_atms at hotmail.com
Sat Apr 15 02:56:09 PDT 2006
This is similar turf to the DDL project, but I couldn't see any examples
for Windows DLL runtime linking. So I threw this together and while it
works and I do like it, I'm wondering if it can be improved upon.
It lets you define a way to call a function in a DLL without linking in
its import library.
So this -
# alias dllimport!("user32.dll", "MessageBoxW", uint, void*, wchar*,
wchar*, uint) MessageBox;
can be used as you would with a DLL import library, but it's linked at
runtime -
# MessageBox(null, "Hello", "World", 0);
Now, here's the template code that does the magic.
# template signature(R, T0 = void, T1 = void, T2 = void, T3 = void) {
# static if (!is(T3 == void))
# extern (Windows) alias R function(T0, T1, T2, T3) signature;
# else static if (!is(T2 == void))
# extern (Windows) alias R function(T0, T1, T2) signature;
# else static if (!is(T1 == void))
# extern (Windows) alias R function(T0, T1) signature;
# else static if (!is(T0 == void))
# extern (Windows) alias R function(T0) signature;
# else
# extern (Windows) alias R function() signature;
# }
# template functor(char[] dllName, char[] entryPoint, R, T0 = void, T1 =
void, T2 = void, T3 = void) {
# static if (!is(T3 == void)) {
# static R opCall(T0 t0, T1 t1, T2 t2, T3 t3) {
# return (cast(signatureT)GetProcAddress(LoadLibraryA(dllName),
entryPoint))(t0, t1, t2, t3);
# }
# }
# else static if (!is(T2 == void)) {
# static R opCall(T0 t0, T1 t1, T2 t2) {
# return (cast(signatureT)GetProcAddress(LoadLibraryA(dllName),
entryPoint))(t0, t1, t2);
# }
# }
# else static if (!is(T1 == void)) {
# static R opCall(T0 t0, T1 t1) {
# return (cast(signatureT)GetProcAddress(LoadLibraryA(dllName),
entryPoint))(t0, t1);
# }
# }
# else static if (!is(T0 == void)) {
# static R opCall(T0 t0) {
# return (cast(signatureT)GetProcAddress(LoadLibraryA(dllName),
entryPoint))(t0);
# }
# }
# else {
# static R opCall() {
# return (cast(signatureT)GetProcAddress(LoadLibraryA(dllName),
entryPoint))();
# }
# }
# }
# struct dllimport(char[] dllName, char[] entryPoint, R, T0 = void, T1 =
void, T2 = void, T3 = void) {
# alias signature!(R, T0, T1, T2, T3) signatureT;
# mixin functor!(dllName, entryPoint, R, T0, T1, T2, T3);
# }
There are some issues, obviously. FreeLibrary doesn't get called (fairly
straightforward to solve). And it should check if both the DLL and
function were found, throwing an exception if not.
My main question is this: can I get rid of the struct, maybe replacing
it with a delegate? I've been staring at it for so long I can't see the
alternatives.
Cheers.
More information about the Digitalmars-d
mailing list