2011-03-08 141 views
6

我不是一個真正的CS人,所以如果你們中的任何一位天才都能指引我走向正確的方向,我會永遠感激。float * from C to C#

我有一個c代碼命令行函數,用於將其結果寫入文件。我將它轉換到經由浮子*陣列返回它的數據到像這樣(以避免恆定文件I/O)C++程序:

float * mgrib(int argc, char **argv) 

這完美地工作。我現在需要把它變成一個C#程序,這裏是事情發生的地方。

我爲避免char **所做的第一件事是將參數設置爲一系列布爾值。如果我允許它仍然轉儲到文件,那工作正常。

問題是在C#中雜耍C風格的浮動數組。在c代碼中,它被分配了malloc。

因此,這裏的一切,我沒有成功嘗試(我知道數組的大小):

  1. 做一個「免費」的功能,以出口從C#打電話的時候我來釋放內存米做完了。幾次循環後,C#崩潰,沒有任何警告。

  2. 從Marshal.FreeCoTaskMem的C#發佈malloc。同樣的結果。

  3. 將float *移動到參數並移除c代碼malloc。 (void mgrib(...,float * data,...)

__a)將其與Marshal.AllocCoTaskMem一起分配。用Marshal.FreeCoTaskMem免費。

__b)使用Marshal.Copy分配。免費與Marshal.FreeCoTaskMem它(也許這是錯的?)

我已經涉足了我可以在互聯網上找到的一切。如果需要更多信息,請讓我知道。我希望這只是一個簡單的概念,我錯過了。

+5

忘了C語言,寫一個乾淨的用C#。而是返回一個浮點數組(float [])。 – stefan 2011-03-08 18:30:41

+1

請發佈您的C#代碼 – 2011-03-08 18:39:09

+2

您是否試圖做到這一點,或容易嗎?簡單的方法是將兩個程序幾乎保持完好,但通過管道而不是文件進行通信。要做得好,你最好用一種語言編寫整個程序。 – 2011-03-08 19:12:29

回答

4

將此簽名用於C函數(將mgrib.dll替換爲真實的庫名稱)。

[DllImport("mgrib.dll", EntryPoint = "mgrib")] 
public static extern IntPtr mgrib(
    int argc, 
    [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] 
    StringBuilder[] argv); 

調用mgrib功能如下:

// Prepare arguments in proper manner 
int argc = 0; 
StringBuilder[] argv = new StringBuilder[ argc ]; 
IntPtr pointer = mgrib(argc, argv); 

當呼叫完成後,你可以得到的結果是這樣的:

float[] result = new float[ size ]; 
Marshal.Copy(pointer, result, 0, size); 

編輯

由於mgrib是一個使用malloc來定位內存,我們需要使用free函數釋放內存。但是,您將不得不將呼叫包裝到free函數中,以便從本機庫導出另一個函數。

extern "C" __declspec(dllexport) void mgrib_free(float* pointer); 

void mgrib_free(float* pointer) 
{ 
    free(result); 
} 

然後將其導入到這樣的:

[DllImport("mgrib.dll", EntryPoint = "mgrib_free", 
      CallingConvention = CallingConvention.Cdecl)] 
public static extern void mgrib_free(IntPtr pointer); 

,並按如下調用它:

mgrib_free(pointer); 
+0

休息,非常感謝您的詳細回覆。這實際上正是我爲我的許多嘗試之一所做的。你的回答讓我有信心深入一點,逐步完成每一次迭代(唉)。我發現無論程序訪問256次mgrib後程序崩潰都沒有警告。這有點太巧合了。我正在使用Marshal.FreeCoTaskMem。 Marshal.FreeHGlobal拋出一個句柄錯誤。所以我認爲現在FreeCoTaskMem並沒有完全削減它,但內存不會被釋放。任何想法的人? – Anthony 2011-03-09 02:13:10

+0

@Anthony:新信息有幫助嗎? – 2011-03-09 21:08:08

+0

這是我嘗試的第一件事,但在我學會了如何使用IntPtr之前。我會試一試。感謝您回到這裏。 – Anthony 2011-03-10 20:33:25