代码之家  ›  专栏  ›  技术社区  ›  Gina Marano

c#封送null终止字符串数组

  •  0
  • Gina Marano  · 技术社区  · 7 年前

    我正在尝试导入以下内容:

    const char * const *object_get_prop_names(propobject_t *ocr);
    

    作为:

    [DllImport("vender.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    private static extern IntPtr object_get_prop_names(int* osr);
    

    基于: https://limbioliong.wordpress.com/2011/08/14/returning-an-array-of-strings-from-c-to-c-part-1/

    我尝试了以下方法:

    var pNames = object_get_prop_names(hdl);
    
    int StringCount = 200; //how do I know string count?
    
    IntPtr[] pIntPtrArray = new IntPtr[StringCount];
    ManagedStringArray = new string[StringCount];
    
    Marshal.Copy(pNames, pIntPtrArray, 0, StringCount);
    
    for (int i = 0; i < StringCount; i++)
    {
        ManagedStringArray[i] = Marshal.PtrToStringAnsi(pIntPtrArray[i]);
        //Marshal.FreeCoTaskMem(pIntPtrArray[i]); crashes
    }
    
    //Marshal.FreeCoTaskMem(pUnmanagedStringArray); crashes
    

    这是可行的,但我猜我有内存泄漏,访问内存我不应该。

    我应该如何释放内存?

    我怎么知道伯爵?这是供应商提供的,他们不会为little ol'me修改dll.:)

    也请原谅我深入研究了一些我知之甚少的事情。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Gina Marano    7 年前

    遵循Hans的建议:

    var pNames = object_get_prop_names(hdl);
    if (h == IntPtr.Zero)
    {
        return null;
    }
    
    var nameList = new List<string>();
    int elementSize = Marshal.SizeOf(typeof(IntPtr));
    
    for (int i = 0; i < 200; i++) //don't know length, pick large number
    {
        var ptr = Marshal.ReadIntPtr(pNames, i * elementSize);
        var str = Marshal.PtrToStringAnsi(ptr);
        if (!string.IsNullOrWhiteSpace(str))
        {
            nameList.Add(str);
        }
        else //end of pNames
        { 
            break; 
        }
    }