c# - char** DllImport 失败

标签 c# char dllimport pointer-to-pointer

我想 DllImport 以下功能。然而,“ret”返回 true,但我的字符串数组似乎是空的,所以我想我可能需要一些编码(marshal)处理。欢迎任何提示!提前致谢:)

C 函数:

bool getBootLog(char **a1);

以下代码用于测试,无法正常运行。

DllImport:

[DllImport("ext.dll")]
public static extern bool getBootLog(string[] bootLog);

当前代码:

        string[] bootLog = new string[1024 * 1024];
        bool ret = getBootLog(bootLog);

        foreach (string s in bootLog)
        {
            Debug.WriteLine(s);
        }

2 次尝试无效:

var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
try
{
    getBootLog(out ptr);
    var deref1 = (string)Marshal.PtrToStringAnsi(ptr);
    Debug.WriteLine(deref1);
}
finally
{
    Marshal.FreeHGlobal(ptr);
}

var ptr2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
try
{
    getBootLog(out ptr2);
    var deref1 = (IntPtr)Marshal.PtrToStructure(ptr2, typeof(IntPtr));
    var deref2 = (string[])Marshal.PtrToStructure(deref1, typeof(string[]));
    Debug.WriteLine(deref2);
}
finally
{
    Marshal.FreeHGlobal(ptr2);
}

莫森的想法:

[DllImport("Ext.dll")]
public static extern bool getBootLog(StringBuilder bootLog);

try
{
    int bufferSize = 50;
    StringBuilder bootLog = new StringBuilder(" ", bufferSize);
    Debug.WriteLine("Prepared bootLog...");
    getBootLog(bootLog);
    Debug.WriteLine("Bootlog length: " + bootLog.Length);
    string realString = bootLog.ToString();
    Debug.WriteLine("Bootlog: " + realString);
}
catch(Exception ex)
{
    Debug.WriteLine("Xception: " + ex.ToString());
}

结果:

Prepared bootLog... Bootlog length: 0 Bootlog:

最佳答案

修改声明:

[DllImport("ext.dll", CharSet = CharSet.Ansi)]
public static extern bool getBootLog(ref IntPtr bootLogPtr);

代码编辑版本中尝试的行看起来不正确。

var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));

确实,应该指定缓冲区的大小。

var ptr = Marshal.AllocHGlobal(100); // Set it to 100 bytes, maximum!

将长度写入 ptr,作为其 C 风格的空终止字符串。

Marshal.WriteByte(ptr, 100, 0);

然后调用将在我脑海中出现的调用:

IntPtr ptrBuf = ptr;
getBootLog(ref ptrBuf);

通过ptrBuf将缓冲区的内容复制到字符串变量中:

string sBootLog = Marshal.PtrToStringAnsi(ptrBuf);

清理非托管内存内容:

Marshal.FreeHGlobal(ptr);

关于c# - char** DllImport 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37531465/

相关文章:

c# - WPF 线程和 GUI 如何从不同的线程访问对象?

c - 如何删除 char 数组转换为无符号 char 数组的警告

c# - 在 Windows 7 中隐藏桌面项目 - 不工作

c++ - 如何在 .NET 中使用托管 DLL 中的非托管类?

c# - C 无符号 `char ** out` 到 C# `byte[]`

c# - 在点上拆分字符串,但不在圆括号内的点上拆分

c# - 如何在 vspackage 中获取当前解决方案配置?

c# - 确定单击一次发布目录

c - 显示地址给出的字节内容

c - 字符数组末尾的意外字符 - C