2011-03-19 180 views
2

我在C++中创建了dll,并且想用c#调用函数。如果函数,程序调用,返回字符串,我有一个错误。 DLL的代码:在从C#代码调用dll函数时出错代码

#include <string> 
using namespace std; 
#define EXPORT_API extern "C" __declspec(dllexport) 
EXPORT_API void DllFunc() 
{ 
    MessageBoxA(0,"DDL box", "Yeah!", 0); 
} 

EXPORT_API string DllFuncStr() 
{ 
    return "testStr"; 
} 

C#应用程序代码:

[DllImport("dllka.dll")] 
static extern void DllFunc(); 
[DllImport("dllka.dll")] 
static extern string DllFuncStr(); 

private void btnStart_Click(object sender, RoutedEventArgs e) 
{ 
    DllFunc(); 
    string str = DllFuncStr();   
} 

“DllFunc();” - 工作很好,但在线“字符串str = DllFuncStr();”我有一个错误:

运行时遇到一个致命错误。错误的地址是0x5e6dceca,线程0x16b0。错误代码是0xc0000005。此错误可能是CLR中的错误,也可能是用户代码中不安全或不可验证的部分。此错误的常见来源包括COM-interop或PInvoke的用户编组错误,这可能会破坏堆栈。

什么是错的字符串类型?如何解决这个问题?

回答

5

不能元帅的std ::从C++字符串到C#。而是使用以StringBuilder编组的零终止字符串,或者返回一个BSTR。

BSTR方法非常简单。如果您更喜欢以零结尾的字符串,那么请在Web上查找来自Win32 API的示例P/Invokes,例如GetWindowText函数()。

您是从C++与cdecl调用约定,但在C#代码中使用STDCALL出口。将数据类型编组后,您需要匹配这些数据类型。无论你使用哪一种,只要它在两端都是一样的。

您还需要戳破你的C++代码使用CHAR(8位编码)和C#的事实使用Windows自带UTF-16。

如果是我,我会用BSTR做到这一点,因为我在this answer勾勒出了另一个问题。

3

正如David所说,C++ std :: string和c#string是不同的东西。我做到了以下在我的应用方式:

C++ DLL代码:

EXPORT_API void DllFuncStr(char* sRetText, int nCapacity) 
{ 
    if(!sRetText) 
    return; 

    std::string sRetTextStr("testStr"); 

    strcpy_s(sRetText, nCapacity, sRetTextStr.c_str()); 
    return; 
} 

C#应用程序代码:

[DllImport("dllka.dll")] 
static extern bool DllFuncStr(StringBuilder sStrBuilder, int nCapacity); 

private void btnStart_Click(object sender, RoutedEventArgs e) 
{ 
    StringBuilder strBuilder = new StringBuilder(50); 
    DllFuncStr(strBuilder, strBuilder.Capacity); 
    string str = strBuilder.ToString(); 
} 

(谢谢汉斯建议,我会修。这个东西也在我的应用中)

+2

这是一个很好的方法。但是,添加一个说明缓冲区有多大的参数是至关重要的。不这样做会因缓冲区溢出而导致堆损坏,非常难以调试。通过StringBuilder.Capacity。另外,strcpy_s()很好,但是你使用不正确。如果您传递字符串长度而不是缓冲区长度,它可以*从不*提供保护。 – 2011-03-19 21:32:22

+0

谢谢。我修复了代码。 – jing 2011-03-19 21:45:37

+0

你做到了。但是要么使用strcpy()要么修复strcpy_s()参数。让它轰炸程序通常是更好的选择顺便说一句,布尔返回值往往被忽略。不幸的是,这是一个非常不友好的炸弹。 – 2011-03-19 22:57:50