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.
On Mon, Jun 27, 2005 at 11:53:34AM +0200, Giuseppe AMATO wrote:
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..."
Very likely you have a mixup between stdcall and cdecl calling convention.
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.
Are you sure? Do even the win32 version have cdecl calling convention?
Ciao, Marcus