【问题标题】:Sending a C# string as an argument to a unmanaged C++ DLL function将 C# 字符串作为参数发送到非托管 C++ DLL 函数
【发布时间】:2011-06-07 19:26:51
【问题描述】:

我想将我的 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 签名的调用约定和参数是否与目标非托管签名匹配。

知道如何解决我的问题/从这里做什么?

【问题讨论】:

  • OPENGLHOOK_API 扩展为什么?
  • 简单的 __declspec(dllexport) 定义
  • 我希望它是.. 我可以关闭 MDA,但这并不能解决我的问题,不是吗?
  • @David :这意味着你的函数被导出为__cdecl,但.NET P/Invoke 默认需要__stdcall。您需要协调这些。

标签: c# c++ dll interop


【解决方案1】:

我认为问题在于两种语言之间的默认调用约定。我相信 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);

【讨论】:

  • 谢谢,我在哪里做这个?我要替换 __declspec(dllexport) 吗? - NVM 得到它,效果很好,谢谢
  • C++ 不应该是 int __stdcall installHook(wchar* directory),即没有 OPENGLHOOK_API 因为 OPENGLHOOK_API 扩展为 __declspec(dllexport) 吗?
【解决方案2】:

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

【讨论】:

  • C# __stdcall 的默认调用约定不是独立于平台的吗?
  • @Brandon Moretz:x64 没有不同的调用约定。
  • @Downvoter :按照这个答案的建议去做就可以完全解决 OP 的问题;为什么投反对票?
  • 不好意思说的这么粗,但是你在哪里明确描述了非托管字符串类型呢?
猜你喜欢
  • 2017-02-09
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
相关资源
最近更新 更多