将C#字符串作为参数发送到非托管C++DLL函数

本文关键字:函数 C++DLL 字符串 参数 | 更新日期: 2023-09-27 17:58:40

我想把我的C#字符串发送到C++DLL函数。我已经成功了,两者都使用StringBuilder:

[C#]
public static extern int installHook(StringBuilder directory);
StringBuilder myText = new StringBuilder(512);
myfunc(myText);
[C++]
int OPENGLHOOK_API myfunc(char* directory)
{
    ::MessageBoxA(NULL,directory,"test123",0);
}

并且用一个简单的字符串&wchar:

[C#]
public static extern int installHook(string directory);
myfunc("myText");
[C++]
int OPENGLHOOK_API installHook(wchar* directory)
{
    wstring s = directory;
    const wchar_t* wstr = s.c_str();
    size_t wlen = wcslen(wstr) + 1;
    char newchar[100];
    size_t convertedChars = 0;
    wcstombs_s(&convertedChars, newchar, wlen, wstr, _TRUNCATE);
    ::MessageBoxA(NULL,newchar,"test123",0);
}

正如StackOverflow上的其他线程中提到的那样。问题是,每次我这样做时,我都会得到一个错误,因为函数签名不一样:

托管调试助手"PInvokeStackImbalance"在"C:''Users''Dave''Documents''Visual Studio 2010''Projects''OpenGLInjector''Loader''bin''Release ''Loader.vshost.exe"中检测到问题。附加信息:调用PInvoke函数"Loader!Loader.Form1::myfunc'使堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标签名不匹配。请检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。

你知道我该怎么解决我的问题吗?

将C#字符串作为参数发送到非托管C++DLL函数

我认为问题在于两种语言之间的默认调用约定。我相信C#是__stdcall,C++是__cdecl。尝试在C++方法签名上显式声明__stdcall,看看这是否不能解决错误。

C++:

int OPENGLHOOK_API __stdcall installHook(wchar* directory)

C#:

[DllImport( "yourdll.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode )]
static extern int installHook(string directory);

您需要明确描述32位的非托管调用约定,此外,您还需要明确描述非托管字符串类型-ASCII、UTF16等。