Skip to main content
 首页 » 编程设计

c#之将 C 字符串引用传递给 C#

2024年02月24日25mayingbao

代码

extern "C" __declspec(dllexport) int export(LPCTSTR inputFile, string &msg) 
{ 
    msg = "haha" 
} 

C#代码

[DllImport("libXmlEncDll.dll")] 
public static extern int XmlDecrypt(StringBuilder inputFile, ref Stringbuilder newMsg) 
} 

当我尝试检索 newMsg 的内容时出现错误,提示我正在尝试写入 protected 内存区域。

从 c 到 c# 检索字符串的最佳方法是什么。谢谢。

请您参考如下方法:

即使在 C++ 中,使用带有以 C++ 类作为参数的导出的 DLL 也是危险的。与 C# 互操作是不可能的。您不能使用相同的内存分配器,也不能调用构造函数和析构函数。更不用说您的 C++ 代码无效,它实际上并不返回字符串。

改用 C 字符串。让它看起来像这样:

extern "C" __declspec(dllexport)  
void __stdcall XmlDecrypt(const wchar_t* inputFile, wchar_t* msg, int msgLen) 
{ 
    wcscpy_s(msg, msgLen, L"haha"); 
} 

[DllImport("libXmlEncDll.dll", CharSet = CharSet.Auto)] 
public static extern void XmlDecrypt(string inputFile, StringBuilder msg, int msgLen) 
... 
    StringBuilder msg = new StringBuilder(666); 
    XmlDecrypt(someFile, msg, msg.Capacity); 
    string decryptedText = msg.ToString(); 

这些代码片段的一些注释:

  • __stdcall 声明符为 DLL 导出选择标准调用约定,这样您就不必在 [DllImport] 属性中使用 CallingConvention 属性。
  • C++代码使用wchar_t,适合存放Unicode字符串。当您从 XML 文件中获取的文本被转换为 8 位字符(有损转换)时,这可以防止数据丢失。
  • 选择正确的 msgLen 参数对于保持此代码的可靠性很重要。不要省略它,如果 C++ 代码溢出“msg”缓冲区,它将破坏垃圾收集堆。
  • 如果您确实确实需要使用 std::string,那么您需要用 C++/CLI 语言编写一个 ref 类包装器,以便它可以从 System.String 转换为 std::字符串。