coffeenet says:
1- How can the DLL trigger callback functions that will eventually call functions inside the EXE.
The piece of code you kindly provided above:
2- Where should it go, DLL or EXE?
It seems no matter what way you go you end up using pointers to functions.
This looks daunting, but is rather simple.
I will answer
2 first because it is quick.
The code to dynamically load a function would go in the exe. That would then get a handle to your DLL and load functions from the DLL.
Now for 1.
We use
typedef
to declare a variable type. This is not required, but simplifies things later.
The syntax of a function type definition is
RETURN_TYPE (CALL_CONVENTION *FunctionTypeName)(PARAMETERS)
CALL_CONVENTION
is often left out for functions you write as you just use the default.
RETURN_TYPE
includes pointers and/or references (references are only available in C++)
PARAMETERS
can be copied directly from the function definition in the .h file or implementation in the .c file.
Parameter names and in/out can be removed to compress the size of the line if you wish.
Lets pass the function
strstr
into another function as a parameter
_Check_return_ _CRTIMP _CONST_RETURN char * __cdecl strstr(_In_z_ const char * _Str, _In_z_ const char * _SubStr);
typedef _CRTIMP _CONST_RETURN char *(__cdecl *func_strstr)(_In_z_ const char * _Str, _In_z_ const char * _SubStr);
typedef const char *(__cdecl *func_strstr)(const char *, const char *);
typedef const char *(*func_strstr)(const char *, const char *);
Now that you know how to define a function as a parameter type, we need to use it.
The variable type that is defined as a function (
func_strstr
in our case) can be used in the exact same way as any other pointer, with 1 addition. It can now be used as a function name to be called.
Keeping with the
strstr
, you would define a function in the DLL like
__declspec(dllexport) const char *FindSubString(func_strstr pStrStr, const char *szStr, const char *szSubStr) {
return pStrStr(szStr, szSubStr);
}
And to use this function from the exe you would have
__declspec(dllimport) const char *FindSubString(func_strstr pStrStr, const char *szStr, const char *szSubStr);
char *szStr = "hello world";
char *szSubStr = "lo";
char *szLocation = FindSubString(&strstr, szStr, szSubStr);
In the above we have
FindSubString(&strstr, szStr, szSubStr);
which is where the interesting bit happens.
The
&strstr
is passing a pointer to the function
strstr
into the function
FindSubString
.
The ampersand symbol & is optional. I prefer to use it as you are passing in a pointer to the function.
If you have understood everything so far you may have realised that this example is completely pointless as it performs the exact same operation as
char *szStr = "hello world";
char *szSubStr = "lo";
char *szLocation = strstr(szStr, szSubStr);
however the string comparison is done in the context of the DLL.
As for "triggering" a callback, it is up to you when it is triggered. Just pass the function pointer for the function from the exe into the function that is in the DLL and call it as I have shown.
The method of passing function pointers around can also be used for passing a function back from the DLL to the exe as well. The exact same principal applies, however you will probably be passing the function pointer back as the return value of a function.