【问题标题】:Pass a reference of string from C# to C++ function将字符串的引用从 C# 传递给 C++ 函数
【发布时间】:2014-06-18 08:06:04
【问题描述】:

我有一个 C++ 库,并在其中编写了一些函数。
此函数必须返回一个整数和一个字符串。 (2 个输出),我将从我的 C# 程序中调用此函数。
这是我的 C++ 代码:

extern "C"{

    __declspec(dllexport)   UINT Read(OUT char* Temp )
    {
    .....
    }  
}  

这是我在 ImportDll 类中的 C# 代码:

[DllImport("Library.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern uint Read(char[] temp);  

在我的表格中我有这个:

char[] str = new char[256];  
ImportDLL.Read(str);  

它正确返回一个 Int 但字符串结果(str 数组)完全为零(\0)!
我的代码有什么问题?
谢谢。

【问题讨论】:

  • 为什么要用char[],可以用string。
  • 如果你有dll代码,那么你可以调试“读取”函数,看看函数内部发生了什么。

标签: c# c++ mfc


【解决方案1】:

对 Matthew Watson 的回答有一个补充:您还需要将 stringbuilder 参数编组为 LPSTR (char *),例如

[DllImport("Library.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern uint Read([MarshalAs(UnmanagedType.LPStr)] StringBuilder temp);

【讨论】:

    【解决方案2】:

    由于返回值为 OUT,我假设它是由 C++ 方法创建的。

    在这种情况下,您可能需要将 StringBuilder 传递给它:

    [DllImport("Library.dll", CallingConvention = CallingConvention.Cdecl, CharSet=CharSet.Unicode)]
    public static extern uint Read(StringBuilder temp);  
    

    请注意,您还应该指定字符集,这取决于您的 C++ 代码使用的字符编码 - ANSI 或 Unicode。

    要调用它,创建一个足够大小的新 StringBuilder 并将其传递给Read(),然后在Read() 返回后使用 StringBuilder.ToString() 检索字符串。

    如果 C++ 函数需要一个特定大小的字符串缓冲区,则需要创建至少为该大小的 StringBuilder,例如:

    const int BUFFER_SIZE = 128;
    var sb = new StringBuilder(BUFFER_SIZE);
    Read(sb);
    var result = sb.ToString();
    

    注意:如果不了解 C++ 函数的细节,很难说这是否真的是正确的解决方案。可能你只需要传递一个字符串。

    【讨论】:

    • 非常感谢,这很有帮助,但正确答案是:[MarshalAs(UnmanagedType.LPStr)] StringBuilder temp
    猜你喜欢
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 2013-05-21
    • 2015-09-09
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多