【问题标题】:Convert IntPtr to char** in C#在 C# 中将 IntPtr 转换为 char**
【发布时间】:2015-08-06 17:21:34
【问题描述】:

我想解释以下非托管函数的输出:

afc_error_t afc_get_device_info (afc_client_t client, char ***device_information)

我用代码导入dll:

[DllImport("libimobiledevice.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern short afc_get_device_info(IntPtr client, out IntPtr info);

只要我只需要将响应转换为字符串Marshal.PtrToStringAnsi 就可以了。但是我不知道如何将该 IntPtr 转换回 char 数组。

【问题讨论】:

  • 您正在导入两个不同的函数,具有不同的名称和不同数量的参数...而第一个是 char***...(我不得不说,*** 是即使在 C 世界中也很少见 :-) )
  • @xanatos 是的,对不起,我更正了名称。 char*** 是因为它返回一个 char**(例如,如果它返回一个字符串,它将是 char** outputString)。
  • @geislza,第二个示例是您正在使用的同一库的不相关方法的示例,对吧?
  • @xanatos 如果您的意思是 Marshal.PtrToStringAnsi,那么是的,它用于另一个函数。

标签: c# memory-management types type-conversion dllimport


【解决方案1】:

应该是这样的:

IntPtr di;

int result = afc_read_directory(client, @"C:\", out di);

if (di == IntPtr.Zero)
{
    throw new Exception();
}

IntPtr di2 = di;

while (true)
{
    IntPtr ptr = Marshal.ReadIntPtr(di2);

    if (ptr == IntPtr.Zero)
    {
        break;
    }

    string str = Marshal.PtrToStringAnsi(ptr);

    if (str == string.Empty)
    {
        break;
    }

    di2 = di2 + IntPtr.Size;
}

试试它是否有效,然后我会解释如何......

重要你在这里泄漏内存......

我在 C 语言中找到了这个示例:

char **dirs = NULL;
afc_read_directory(afc, "/eafaedf", &dirs);
if (!dirs)
    afc_read_directory(afc, "/", &dirs);
printf("Directory time.\n");
for (i = 0; dirs[i]; i++) {
    printf("/%s\n", dirs[i]);
    free(dirs[i]);
}
if (dirs)
    free(dirs);

负责释放内存(见循环内的free和最后的free?)。在这种情况下(对于返回 C 字符串数组的其他方法,您可以使用 afc_dictionary_free。请注意,其他方法(如 afc_receive_data)返回单个内存块,您不能使用它。

【讨论】:

  • 谢谢,成功了。在同一个库中有一个 afc_dictionary_free 函数。我认为这可以正确释放。
  • @Geiszla 是的......确实如此。刚看了它的源代码。
  • @Geiszla 如果您想使用该方法,请注意您必须更改代码。我已经更新了答案。我正在修改原始的IntPtr di,但您需要保留一份副本才能与afc_dictionary_free 一起使用
猜你喜欢
  • 1970-01-01
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 2021-11-30
  • 1970-01-01
相关资源
最近更新 更多