问题
This is an elaboration to an earlier question: How to reset state machines when unit testing C
There is also a similar question but i don't the answer match my problem and i have some examples i wish to present: Exporting a function pointer from dll
I have two sets of code that i expect should do the same but the latter crashes. Using mingw32 and Win7.
The function to be exported. This is to be considered legacy and unmutable.
addxy.c
int addXY(int x, int y)
{
return x + y;
}
addxy.h
int addXY(int x, int y);
The working example
main.c
#include <stdio.h>
#include "addxy.h"
typedef int (__cdecl *addXYWrap_t)(int a, int b);
addXYWrap_t addXYWrap = (addXYWrap_t)addXY;
void main()
{
printf("result: %d", addXYWrap(3, 4));
}
Yielding
result: 7
The crashing example
addxydll.c
#include <stdio.h>
#include "addxy.h"
typedef int (__cdecl *addXYWrap_t)(int a, int b);
__declspec(dllexport) addXYWrap_t addXYWrap = (addXYWrap_t)addXY;
main.c
#include <windows.h>
#include <stdio.h>
typedef int (__cdecl *func)(int a, int b);
void main()
{
HINSTANCE loadedDLL = LoadLibrary("addxy.dll");
if(!loadedDLL) {
printf("DLL not loaded");
return;
} else {
printf("DLL loaded\n");
}
func addition = (func)GetProcAddress(loadedDLL, "addXYWrap");
if(!addition) {
printf("Func not loaded");
return;
} else {
printf("Func loaded\n");
}
printf("result: %d", addition(3, 4));
}
Yielding
DLL loaded
Func loaded
before it chrashes.
The crash gives no information as to why or what.
Is it a syntactical error or conceptional one?
回答1:
func addition = (func)GetProcAddress(loadedDLL, "addXYWrap");
This call to GetProcAddress
returns the address of addXYWrap
, not its value. Since addXYWrap
is a function pointer (of the same type as func
), that means it returns a pointer to a function pointer, or a func*
.
Try changing that line to this:
func addition = *(func*)GetProcAddress(loadedDLL, "addXYWrap");
Or, alternatively:
func* addition = (func*)GetProcAddress(loadedDLL, "addXYWrap");
and then (*addition)(3, 4)
回答2:
So, based on comments above, you appear to be overthinking it. If you did need a function pointer, then to correctly call it, you must first dereference GetProcAddress
like so:
func addition = *(func*)GetProcAddress(loadedDLL, "addXYWrap");
However, a much more convenient solution is to just wrap the function:
__declspec(dllexport) int myAddXY(int x, int y)
{
return addXY(x, y);
}
回答3:
int addXY(int x, int y)
{
return x + y;
}
__declspec(dllexport) addXYWrap_t addXYWrap = (addXYWrap_t)addXY;
This is an error. You have to export function, not a global pointer. That is,
/* addxy.c */
__declspec(dllexport) int addXY(int x, int y)
{
return x + y;
}
....
/* main.c */
func addition = (func)GetProcAddress(loadedDLL, "_addXY");
来源:https://stackoverflow.com/questions/33667049/exporting-a-function-cast-into-a-pointer-through-a-dll