I have some general purpose functions defines in my exe file like Log(char* str)
. This function takes a string as an input from the caller and writes it to the logfile defined for that application. Now I want to write DLL code which will include a function to upload a file to a server.
The objective is to import the upload function from the DLL into the exe and use it. However, if any error is encountered, then the upload function must call the Log(char* str)
function to write the error into the log file.
The trouble is that this DLL needs to be used in multiple applications and each app will have a different logfile at a different location. I want to write the DLL in such a way that it calls the corresponding Log(char* str)
defined in the application. Similarly I have some other functions that are application-specific and cannot be included in the DLL beforehand.
How can I write such DLL code where it only knows the function prototype, but not the function definition, which resides inside the exe?
The information's in these links are for the cases where the DLL is loaded by the EXE and hence the DLL can call the exported functions of the EXE. But for my case EXE and DLL are independent of each other or the EXE is invoked by the DLL using CreateProcess().
To access a function in a dll, there's two main methods: Use dllimport, similarly to how you exported the functions with dllexport. Load the DLL using LoadLibrary, then get a pointer to your function with GetProcAddress.
Both of these include executable code, however, DLL and EXE operate differently from one another. The EXE will create its own thread and reserve resources for it if you run it. A DLL file, on the other hand, is an in-process server, so you cannot run a DLL file on its own.
Have a function in your DLL that the .exe can call, passing in a function pointer to your Log
function. Inside the DLL, store that function pointer and use it when you need to log things.
If there is more than one such function you need to pass to your DLL, consider using a struct
to store all the relevant function pointers.
Here's a good tutorial on function pointers: The function pointer tutorial
To keep this interface simple, I would highly recommend keeping all these "customizable" functions in plain C
, at least as a starting point. Dealing with pointer-to-member functions and passing C++
objects around through C
wrappers is error-prone. (But doable.) Or stick with C++
all round.
Here's a short example. In a common header, put something like this:
typedef void (*logfunc)(char const*);
to simplify passing around the customized function pointer.
In your DLL code, you could then have:
logfunc cust_log;
void dll_init_logging(logfunc l)
{
cust_log = l;
}
void dll_do_something()
{
cust_log("hello");
}
Modify that to make these functions exportable if necessary on your platform.
Then from your main code, all you need to do (assuming you're loading the DLL and making the exported functions available to your .exe with their original name) is:
void logit(char const* str)
{
printf("Log: %s\n", str);
}
int main (int argc, char const *argv[])
{
// load the DLL
dll_init_logging(logit);
...
dll_do_something();
...
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With