Reputation: 7579
TL;DR; Is it possible, under wine, to call a function in a Windows exe, by function pointer, from the Linux proxy library?
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:-
1 cdecl foo (ptr ptr) Proxyfoo
morag.c
contains:-
#include <windef.h>
#include <FOO.h> /* def of FOOSTRUCT */
void WINAPI Proxyfoo (long * parm1, FOOSTRUCT * parm2)
{
foo(parm1, parm2);
}
Build command:-
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
This works well. I can successfully call foo
from my Windows application and invoke foo
in the Linux implementation.
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:-
#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);
}
However, this does not work. The ProxyCallbackFn
is successfully called by the Linux implementation of foo
, but my call to SavedCallbackFn
causes SIGSEGV
. I had thought that the "trick" needed was simply to get WINAPI
onto the function definition.
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?
Upvotes: 0
Views: 80