簡體   English   中英

如何將C數組映射和編組為C#代碼

[英]How to map and marshal a C array into a C# code

我正在編寫調用C庫的C#代碼,這在我看來並不是很清楚。

C函數有這個簽名:

double* DoSomeStuff(double* input,int numberOfElements);

我已將函數映射為:

[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint="DoSomeStuff")]
public static extern  System.IntPtr DoSomeStuff(ref double input, int numberOfElements) ;

輸入值是一個數組,因此C函數將期望連續的內存布局。 我比C#更熟悉C ++。 在C ++中,我使用std :: vector來存儲數據,然后我將使用data()方法獲取指針並使用C代碼交換信息。 std :: vector保證了連續的布局內存。

我可以在C#中使用哪種數據結構? 在C#中有什么類似std :: vector的東西嗎?

我面臨着一個字符串的相同問題(在C ++中,std :: string只是一個帶有一些化妝的std :: vector)。 我用以下方法解決了這個問題:

System.IntPtr stringExample = Marshal.StringToHGlobalAnsi("StringExample"); 

靜態功能為我完成了這項工作。 其他類型有什么類似的功能嗎?

我已經問了太多問題,我認為最重要的問題是:解決這類問題的最佳做法是什么?

謝謝

1)

將輸入定義為IntPtr:

[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint="DoSomeStuff")]
public static extern  System.IntPtr DoSomeStuff(IntPtr input, int numberOfElements) ;

2)

固定塊中創建一個數組,然后從指針創建一個IntPtr,然后將其傳遞給DoSomeStuff

double[] input = new double[20];
IntPtr result = IntPtr.Zero;
fixed(double* d = &input[0])
{
    result = DoSomeStuff(new InptPtr(d), 20);
}

...

fixed塊的原因是,當非托管代碼填充時,GC不會移動陣列。

為了使您的示例工作,您應該定義extern函數的siganture,如下所示:

[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint="DoSomeStuff")]
public static extern  System.IntPtr DoSomeStuff([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)], int numberOfElements);

MarshalAs attaribute的第二個(命名)參數告訴編組器存儲數組大小的位置。

關於第二個問題,C#有List<Type>類,其行為類似於std:vector<Type> 但是,我不認為你可以直接提供給編組人員。 你可以做的是使用List類的ToArray()方法來獲得一個數組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM