I have a Windows x64 DLL called morag.dll containing a function foo. I also have a Linux SO called morag.so containing the Linux implementation of foo (same parameters on each platform). I have a Windows application that loads morag.dll that I want to run under wine. I have created the mapping between Windows foo and Linux foo by creating a morag.dll.spec file, and a proxy wrapper and building this using winegcc.
morag.dll.spec contains:-
Code: Select all
1 cdecl foo (ptr ptr) Proxyfoo
Code: Select all
#include <windef.h>
#include <FOO.h> /* def of FOOSTRUCT */
void WINAPI Proxyfoo (long * parm1, FOOSTRUCT * parm2)
{
foo(parm1, parm2);
}
Code: Select all
winegcc -m64 -fPIC -d_WIN64=1 -I various-includes -z muldefs morag.c morag.dll.spec -o morag.dll.so -shared -L various-libraries -lfoo
The issue I am facing is when foo is a function that is given a callback function pointer to run later. Clearly the Windows application that calls foo provides it with a function pointer using Windows x64 conventions, but the Linux implementation of foo is invoking the function pointer under the assumption it is using Linux x64 conventions. So unsurprisingly, it fails.
To try to fix this I have attempted, in the proxy layer coded in morag.c to switch out the function pointer with one that meets Linux x64 conventions, and then when it is called back, drive the originally provided function pointer from the proxy layer with Windows x64 conventions.
So now, morag.c contains:-
Code: Select all
#include <windef.h>
#include <FOO.h> /* def of FOOSTRUCT */
typedef void (WINAPI * CBFN)(long * cbparm);
static CBFN SavedCallbackFn;
void ProxyCallbackFn(long * cbparm)
{
SavedCallbackFn(cbparm);
}
void WINAPI Proxyfoo (long * parm1, FOOSTRUCT * parm2)
{
SavedCallbackFn = parm2->CallbackFn;
parm2->CallbackFn = ProxyCallbackFn;
foo(parm1, parm2);
}
In other words is it possible to call a function in the Windows exe, by function pointer, from the Linux proxy library?
What am I missing?