2016-09-20 115 views
2

我想創建一個C#接口從外部C DLL接收回調。 回調的參數包含指向C結構的指針,它們本身具有指向不同結構的指針。C到C#PInvoke與指針結構

回調簽名:

typedef application_event_result (*application_event_ptr)(abuffertype* read_buffer, abuffertype* write_buffer); 

C語言中的緩衝結構的定義:

typedef struct { 
    uint16 size; 
    uint8* data; 
} anotherbuffertype; 

typedef struct { 
    anotherbuffertype *buffer; 
    uint16 position; 
} abuffertype; 

我知道,回調的C#簽名應該使用「參考」爲指針類型的參數。但是,如何在C#中定義「abuffertype」結構中的指針呢?

到目前爲止,我有在C#中的兩個結構的定義是:

[StructLayout(LayoutKind.Sequential)] 
    public struct anotherbuffer 
    { 
     UInt16 size; 
     IntPtr data; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct abuffer 
    { 
     anotherbuffer buffer; 
     UInt16 position; 
    } 

但是,這並不工作。 C#中「abuffer」的內容並不是C代碼中回調之前的內容。

我是否需要手動解組內部指針,如果是這樣,如何?

回答

2

您不會從編組人員那裏得到幫助,這通常會導致嚴重的內存管理問題。但是可以在回調的特定情況下工作,因爲它是管理數據的調用C程序。

你必須自己轉換數據。聲明指針爲IntPtr並使用Marshal.PtrToStructure()來檢索數據。

anotherbuffertype.data成員看起來像一個數組,使用Marshal.Copy()將其內容複製到您自己的byte []數組中。如果您不介意unsafe關鍵字,那麼您可以將其聲明爲byte *並使用data [index]訪問元素,從而避免複製的成本。它不是非常不安全,很容易將索引限制爲[0..size]。