Loading & calling a function from dll at runtime

Hi
How would i go about making a program that dynamically loads a dll and that then allows me to type a function name (along with its parameter types & their values) in to the console, which the program will then retrieve and call for me?

i already know how to load a dll and how to retrieve a function from it using LoadLibrary() and GetProcAddress()

The main problem is: casting the pointer that is returned from GetProcAddress() to a correct function pointer. (so that i can call it)

Because i will need to somehow typedef a function pointer with the correct parameters and calling convention for the function but the problem is that im getting that infomation at runtime (from the command line) and you cant typedef at runtime


Is there any way at all to solve this?
Last edited on
Heres some example code, maybe it will explain better what im trying to do:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int main()
{
	//Input
	std::string dllPath;
	std::string functionName;
        std::string callingConv;
	std::string arg1; //arg2, arg3, etc..


	std::cin >> dllPath;
	std::cin >> functionName;
        std::cin >> callingConv;
	std::cin >> arg1; 
        //etc..




	//Loading of library & function

	HMODULE hmod;
	void* proc; // <-- dont know type at compile time

	hmod = LoadLibrary( (LPCWSTR) dllPath.c_str());

	if (hmod)
	{
		proc = GetProcAddress(hmod, (LPCSTR) functionName.c_str());

		//...
		//somehow cast proc to a function pointer with the correct type (using the information i got from the input (i.e. the calling convention and parameter types) )
		//...

		if (proc)
		{
			//call proc(arg1, arg2, etc)
		}
	}

	return 0;
}
Last edited on
im getting that infomation at runtime (from the command line)

In other words, if the user does not know the signature of the function that is in the library, then they cannot possibly call it.

Apart from that:
IF ... THEN
  foo p = proc
  p( 42 )
ELSE IF ... THEN
  bar p = proc
  p( 3.14, "snafu" )
I'm assuming this is only a problem because you don't have the library's source code.

Can you wrap the library in your own process, and use IPC? It doesn't look like you know what the DLL is in advance. Are you certain that's a good idea?

If you can not, assuming you know the ABI, you can drop to assembler and perform the work of the function prologue yourself. This is usually done by the compiler, but libffi takes this approach too.

In fact, if you happen to have guarantees that the system-compiler is both present and compatible, you could conceivably generate a simple thunk, run the system compiler, load the compiled code, and call the unknown function through the generated code.

Oh, and the obvious concern:
Why can't you require the DLL to provide a known interface?
Last edited on
Thank you for the responses

The real reason im asking this is actually because i'm wondering how python (and other scripting languages) achives this?

in python there is a function called cdll.LoadLibrary('./library.dll')

all you have to do is call that function and then you can basically just use any of the functions from the dll like any other python function

but how do they do this, if they don't know the dll function signatures when the interpreter is compiled?

do they do the thing mbozzi said? use assembly to do, the function prologue themselves?

(i know they have a thing called ctypes that basically maps from python types to c types, so it seems like that is what they are doing)

but wouldnt that be really dangerous? if you attempted to call a dll function from python with the wrong arguments, wouldnt that completely mess up the stack?
Last edited on
I don't know much about Python, but it appears from the documentation that you're supposed to tell ctypes what the function signatures are. I suppose it deduces parameter types from the arguments, and the return type is user-specified, or int by default:
https://docs.python.org/3/library/ctypes.html

The library functions can appear as class methods since Python allows methods and fields to be added to classes at run-time: Python classes are objects. While I'd have to read ctypes to tell you how it works with any certainty, maybe it tries to locate the library symbol during the method lookup.

[Do they do the work of] the function prologue themselves?

Probably, or they use a library.

But wouldnt that be really dangerous? If you attempted to call a dll function from python with the wrong arguments, wouldnt that completely mess up the stack?

Possible incompatibility is an unavoidable danger of explicit runtime linking. Not even C++ can save you from it:
1
2
3
void (*wrong_kind_of_function_pointer)(int);
*(void **)(&wrong_kind_of_function_pointer) = dlsym(handle, sym); 
// note: dlsym() == GetProcAddress() 
Last edited on
Topic archived. No new replies allowed.