Reputation: 28987
The address of a function has a different value inside and outside a DLL.
Simplifying somewhat, I have the following code in a dll
typedef struct Holder Holder; /* Struct */
typedef int (*pfn_t)(Holder*); /* Function pointer */
struct Holder { pfn_t pfn; }
int IsSame( Holder *h ){ return h->pfn == IsSame; }
In a main program, I have:
Holder h = { IsSame };
assert( IsSame(&h) );
the assert fires! The problem is that h.pfn is set to the address of the jump table in main.exe, whereas the code in the DLL is comparing this with the address of the function in the DLL.
Are there any magic annotations or linker options I can use to persuade the assert to not fire?
Note that this is on Windows. The Posix shared library model is very different (and doesn't have this problem.)
Upvotes: 2
Views: 876
Reputation: 3670
Your problem might be cause of that:
function call goes through an extra JMP instruction .so it is relative address
Instead If you will use LoadLibrary() GetProcAddress()
it will retrieve address of dll function.
Upvotes: 2
Reputation: 1135
If you want to do this kind of function comparison you should use GetProcAddress or export an interface in your DLL that initialises any DLL function pointers to ensure that the addresses that you are comparing are the function address as seen by the module that it resides in rather than the trampoline from the .exe to the DLL which is all part of the Windows loader magic (TM).
Dynamic linkage relies on using trampolines which then jump to entries populated in the Export Address Table. A comparison to an imported function by identifier is only valid within the module it was linked in. Therefore the asumptions behind your code are wrong as they assume that address in the .exe is the address of the function. If you want a constant address of something you need to explicitly export it in the same way you would any data from that module and implicitly import it in any other modules (i.e. GetProcAddress)
Upvotes: 0
Reputation: 28987
I think this is the answer:
http://mingw.5.n7.nabble.com/Direct-dll-linking-and-comparing-function-pointers-td2875.html#a2876
I need to use __declspec(dllimport)
when I declare IsSame
in the main program and __declspec(dllexport)
when I define IsSame in the DLL in order to get the function pointers to be equal.
Upvotes: 1