2017-11-10 119 views
0

我試圖導入以下:C#元帥空值終止字符串數組

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 

這個工程,但我猜我有內存泄漏和訪問內存我不應該。

我該如何釋放內存?

我如何知道計數?這是來自一個供應商,他們不會修改這個dll對我來說很小。 :)

還原諒我鑽研我知道很少的東西。

+1

它返回const char *,所以沒有太多理由擔心釋放字符串。必須有一些*種方法來找出有多少字符串。我會尋找IntPtr.Zero或一個空字符串。您不能安全地使用Marshal.Copy(),直到您知道爲每個元素使用Marshal.ReadIntPtr(),每次通過IntPtr.Size遞增pName。 –

+0

@Hans工作!我閱讀,直到我得到一個空。你能寫出解決方案,以便我可以給你信用? – ginalster

回答

1

繼漢斯的建議:

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; 
    } 
} 

的偉大工程。我無法知道有多少個房產名稱,所以我只需要選擇比可能的房產名稱數量更多的房產。