将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#是__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等。