Hi,
I'm having big troubles using function pointers.
Shortly:
I'm trying to build a Winelib compatible DLL that returns function
pointers; that pointers must be used by a WIN32 app that runs under Wine.
The problem is that the returned function pointers, when directly used
by the WIN32 code, crash the application:
"wine: Unhandled exception (thread 0009), starting debugger..."
In details:
For instance the DLL is a PKCS#11 library.
The PKCS#11 function C_GetFunctionList() returns a structure that
contains pointers to all PKCS#11 functions (so you need to export/use
just the C_GetFunctionList symbol)
struct CK_FUNCTION_LIST
{
CK_C_Initialize C_Initialize;
CK_C_Finalize C_Finalize;
CK_C_GetInfo C_GetInfo;
...
};
CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList);
...
All function have cdecl calling convention.
The problem is:
I need to use a linux-native BINARY PKCS#11 library under a WIN32
program should run with Wine.
As specified in the Winelib docs I've created a Winelib wrapper DLL.
Firts try:
I've wrapped just C_GetFunctionList() and I've exported it using a .spec
file.
The wrapped C_GetFunctionList() loads the native-linux lib and calls the
native C_GetFunctionList(). It just returns function pointers structure
to the calling application without doing any fix-up.
But when the WIN32 program calls any function using a function pointer
contained in CK_FUNCTION_LIST, i.e. C_GetInfo(), the function get called
but the WIN32 program crash just after the function returns:
"wine: Unhandled exception (thread 0009), starting debugger..."
Second try:
Looking at winebuild/winemaker/winegcc I've noticed that a PE-like
export table is automatically created using the .spec file as input. I
can't really understand all implementation details, but looks like that
there is also some code that performs calling convetion
conversion/fix-up (of course from c to stdcall, but there is also some
code for win32-cdecl to gcc-cdecl... ?).
So i've tried to use the winelib's LoadLibrary() and GetProcAddress(),
to "load self" and to get function pointers exactly as a Win32
application would do... hoping that this way I would get pointers to
functions "fixed" for "externa-win32" usage...
But I noticed that fucntion pointers returned by GetProcAddress() are
exactly equal to "internal" fucntion pointers.
I suppose that the GetProcAddress() called from within a Winelib DLL is
"smart" enough to return internal pointers isntead of unusable
"win32-external" pointers...
Third try: not yet done
This is a very complicated way; I think that it should works, but I
wondering if ther isn't a simpler way...
Writing a pure-WIN32 library that exports just C_GetFunctionList and
does the CK_FUNCTION_LIST fix-up (lets call this DLL w32-stub)
the Winelib DLL should stub and export ALL PKCS#11 functions, and not
just C_GetFunctionList() (lets call this DLL winelib-wrapper).
So...
The WIN32 app loads the w32-stub.
The w32-stub loads winelib-wrapper (using LoadLibrary) and load all
PKCS#11 function pointers using GetProcAddress(); this should return
WIN32 usable function pointers.
The winelib-wrapper load the linux-native PKCS#11 library (using
dlopen); all exported functions just wrap native functions of the
linux-native library.