views:

433

answers:

1

I'm trying to call some functions in a DLL compiled with (I believe) Visual C++ from my program, which is compiled using GCC.

To call the functions in the DLL, I do a LoadLibrary() on the DLL, and then a GetProcAddress() to get the address of a particular function, which I then call. This function returns a list of pointers to the functions in the DLL I'm to call.

Well, when I try to call those functions, they don't work properly. I ran my program through a debugger, and it looks like the DLL library function is looking for one of the passed arguments at ebp+8, even though GCC has put it at ebp-24.

It looks definitely like a stack issue. What's more, when the GCC program function which calls the DLL function returns, my program crashes -- so something screwey is going on with the stack. Does anyone know what I need to do in order to fix this? I'm not able to access the DLL code.

Also: I tried putting __cdecl and __stdcall before the DLL function definition in my program's source file, but this changes nothing.

+2  A: 

Looks like a calling convention problem. Make sure you're putting the calling convention tag in the right place. With GCC, it should look like this:

typedef int (__stdcall *MyFunctionType)(int arg1, const char *arg2);
MyFunctionType myFunction = (MyFunctionType)GetProcAddress(myModule, "MyFunction");
// check for errors...
int x = myFunction(3, "hello, world!");

[EDIT]

Looks like your problem has nothing to do with calling conventions (although getting them right is important). You're misusing BSTRs -- a BSTR is not a simple char* pointer. It's a pointer to a Unicode string (wchar_t*), and furthermore, there is a 4-byte length prefix hidden before the first characters of the string. See MSDN for full details. So, the call to SetLicense() should look like this:

BSTR User = SysAllocString(L"");  // Not sure if you can use the same object here,
BSTR Key = SysAllocString(L"");   // that depends on if SetLicense() modifies its
                                  // arguments; using separate objects to be safe
// check for errors, although it's pretty unlikely
(textCapLib.sdk)->lpVtbl->SetLicense((textCapLib.sdk), User, Key);
SysFreeString(User);  // Hopefully the SDK doesn't hang on to pointers to these
SysFreeString(Key);   // strings; if it does, you may have to wait until later to
                      // free them
Adam Rosenfield
Thanks for the response. Unfortunately, that's exactly what it looks like in the C header file.Is there something else majorly different between how VC++ compiles code and how GCC compiles code? Stack alignment, or...?Just a note; in the library header file, it says this is what the compiler settings were when the library was compiled: Oicf, W1, Zp8, env=Win32 (32b run)__declspec(uuid()), __declspec(selectany), __declspec(novtable) DECLSPEC_UUID(), MIDL_INTERFACE()Not sure if that has anything to do with it.
Can you post the code you're using, including the relevant portions of the header file and the calling code?
Adam Rosenfield
Sure. I pasted the header file for the library here: http://pastebin.com/m2d66c18c. I pasted an example (in C) here: http://pastebin.com/m564b3181.I'm using the C interface with GCC. The relevant code begins at line 810 in the header file.I'm able to call Win32 API functions just fine, and according to the header file, the library functions are of the same calling convention as WINAPI functions (STDMETHODCALLTYPE/WINAPI == __stdcall)
I tried that, it makes no difference. There's a sample source code file that comes with the SDK; I actually copied and pasted the code right over, so I figured they were handling the datatypes correctly.Unfortunately, the author of the SDK still hasn't gotten back to me (it's the weekend, I guess), so I'm stuck assuming that everything is correct on their end with the library, and it's an issue on my end.I just download VC++ Express; I'll see if my code works when compiled with it.
Took about an hour to install VC++. So then I tried compiling and running the example application, and I get: "Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."I tried __cdecl, __stdcall, and __fastcall for the project, but it still gave me the error message.What gives? Surely I'm doing something wrong, as the SDK includes a working demo executable that works properly.