Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将C字符串引用传递给C#_C# - Fatal编程技术网

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

将C字符串引用传递给C#,c#,C#,c代码 extern "C" __declspec(dllexport) int export(LPCTSTR inputFile, string &msg) { msg = "haha" } c#代码 当我试图检索newMsg的内容时出错,表示我正在尝试写入受保护的内存区域 从c到c检索字符串的最佳方法是什么。谢谢。< P>使用以C++类为参数的导出的DLL即使在C++中也是危险的。无法与C#进行互操作。不能使用相同的内存分配器,也不能调用构造函数和析构函数。更不用说你的C+

c代码

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

当我试图检索newMsg的内容时出错,表示我正在尝试写入受保护的内存区域


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

< P>使用以C++类为参数的导出的DLL即使在C++中也是危险的。无法与C#进行互操作。不能使用相同的内存分配器,也不能调用构造函数和析构函数。更不用说你的C++代码无效了,它实际上并没有返回字符串。 改用C字符串。让它看起来像这样:

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

以下代码片段的一些注释:

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

使用以C++类为参数的导出的DLL即使在C++中也是危险的。无法与C#进行互操作。不能使用相同的内存分配器,也不能调用构造函数和析构函数。更不用说你的C++代码无效了,它实际上并没有返回字符串。 改用C字符串。让它看起来像这样:

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

以下代码片段的一些注释:

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

    很有效,非常感谢。顺便说一下,我在C#代码中发现了一个问题。字符串inputFile只传递第一个字符。我通过整理它来进行修改

    [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();
    
    再次感谢您。

    汉斯

    很有效,非常感谢。顺便说一下,我在C#代码中发现了一个问题。字符串inputFile只传递第一个字符。我通过整理它来进行修改

    [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();
    

    再次感谢。

    这是因为您忘记了[DllImport]属性中的CharSet属性。请注意我是如何使用CharSet.Auto的,这会让您获得所需的行为。这是因为您忘记了[DllImport]属性中的CharSet属性。请注意我是如何使用CharSet.Auto的,这会使您获得所需的行为。