调用在GCC中使用Visual C ++编译的DLL时出现堆栈问题

时间:2022-09-01 23:46:40

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

我试图在我的程序中使用(我相信)Visual C ++编译的DLL中调用一些函数,该程序是使用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.

要调用DLL中的函数,我在DLL上执行LoadLibrary(),然后使用GetProcAddress()获取特定函数的地址,然后调用该函数。此函数返回指向我要调用的DLL中的函数的指针列表。

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.

好吧,当我尝试调用这些函数时,它们无法正常工作。我通过调试器运行我的程序,看起来DLL库函数正在寻找ebp + 8中传递的参数之一,即使GCC已将它放在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.

它看起来绝对像堆栈问题。更重要的是,当调用DLL函数的GCC程序函数返回时,我的程序崩溃了 - 所以screwey正在进行堆栈。有谁知道我需要做什么来解决这个问题?我无法访问DLL代码。

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

另外:我尝试在程序的源文件中将DLL函数定义放在__cdecl和__stdcall之前,但这没有任何改变。

1 个解决方案

#1


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:

看起来像一个调用约定问题。确保将调用约定标记放在正确的位置。使用GCC,它应该如下所示:

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 - BSTR不是一个简单的char *指针。它是指向Unicode字符串(wchar_t *)的指针,此外,在字符串的第一个字符之前隐藏了一个4字节长度的前缀。有关详细信息,请参阅MSDN。因此,对SetLicense()的调用应如下所示:

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

#1


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:

看起来像一个调用约定问题。确保将调用约定标记放在正确的位置。使用GCC,它应该如下所示:

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 - BSTR不是一个简单的char *指针。它是指向Unicode字符串(wchar_t *)的指针,此外,在字符串的第一个字符之前隐藏了一个4字节长度的前缀。有关详细信息,请参阅MSDN。因此,对SetLicense()的调用应如下所示:

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