2014-01-10 102 views
1

我有一個類定義如下:轉換一個結構到一個IntPtr

[StructLayout(LayoutKind.Sequential)] 
public class OUR_MEM_STR 
      { 
       public byte[] p; 
       public int len; 
      }; 

這是下面的C結構的等效確定指標:

typedef struct 
{ 
    void *p; 
    int len; 
} OUR_MEM_STR; 

我用字節[]代替的IntPtr的爲成員p輸入它正在使用的c#項目的方式。

我與LEN = 10和p =新的字節[10]

我想使它一個IntPtr定義的對象OBJ。我如何獲得對象的大小?

IntPtr pObj = Marshal.AllocHGlobal(obj.len + sizeof(int)); 
Marshal.StructureToPtr(obj, pObj, true); 

看看我在那裏做了什麼。它似乎太硬編碼。如果我做下面的代碼片段;

IntPtr pObj = Marshal.AllocHGlobal(Marshal.SizeOf(obj)); 

否則因爲obj.p返回一個尺寸爲4和由於由指針指向的字節數組截取的存儲器的未10.是4個字節此返回錯誤的大小。

有沒有更好的方法?

+0

你能告訴我們你想要複製的結構的C定義嗎? – JaredPar

+0

@JaredPar,我編輯了問題 –

+0

因此,如果我做IntPtr pObj = Marshal.AllocHGlobal(Marshal.SizeOf(obj));並使用false參數,它應該罰款? –

回答

3

返回值正確,p指針,它需要4個字節。

你不能這樣離開它,有兩個內存分配。編組人員爲陣列分配內存。它創建了一個SAFEARRAY,一個COM數組類型。你的C代碼不會很滿意。聲明它是這樣,而不是:

[StructLayout(LayoutKind.Sequential)] 
public class OUR_MEM_STR { 
    public IntPtr p; 
    public int len; 
}; 

並使用Marshal.AllocHGlobal(10)分配p。不要忘記再次清理。

不通過true to StructureToPtr(),AllocHGlobal()分配的內存未初始化。這會隨機地讓程序崩潰。您必須通過虛假

+0

謝謝! C#垃圾收集不會自動清理? –

+1

不,你分配了非託管內存。調用Marshal.FreeHGlobal()兩次是一個很難的要求。請注意,這必須發生*您的pinvoked代碼停止使用該結構之後。 –

+0

正確。 Lil由律我掌握pinvoke。感謝像你在SO –

相關問題