2011-11-14 21 views
5

我想了解如何從C#數組傳遞到本機函數的解決方案。我已經有一個委託給函數(Marshal.GetDelegateForFunctionPointer),但現在我試圖傳遞一個多維數組(或更確切的說是一個數組數組)。修復在C#中的數組數組(不安全的代碼)

此代碼示例在輸入有2個子數組時可以工作,但我需要能夠處理任意數量的子數組。你能想到的最簡單的方法是什麼?我不希望數據陣列,因爲這之間的複製將在實時循環中發生的事情(我用的音頻效果通信)

public void process(float[][] input) 
{ 
    unsafe 
    { 
     // If I know how many sub-arrays I have I can just fix them like this... but I need to handle n-many arrays 
     fixed (float* inp0 = input[0], inp1 = input[1]) 
     { 
      // Create the pointer array and put the pointers to input[0] and input[1] into it 
      float*[] inputArray = new float*[2]; 
      inputArray[0] = inp0; 
      inputArray[1] = inp1; 
      fixed(float** inputPtr = inputArray) 
      { 
       // C function signature is someFuction(float** input, int numberOfChannels, int length) 
       functionDelegate(inputPtr, 2, input[0].length); 
      } 
     } 
    } 
} 

回答

11

您可以在不使用fixed的情況下將物體固定到位,而不是通過針對所述對象獲取固定的GCHandle。當然,不用說這樣做,你必須承擔責任,確保指針不會超過對象被解除鎖定的點的存活。我們稱之爲「不安全」的代碼是有原因的;您將負責安全的內存管理,而不是運行時間。

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.aspx

+0

我讀過關於GCHandle類的內容。在閱讀你的回覆之後,我試着爲我的電話實施它,它似乎工作得很好。感謝您快速回答。 – Valdemar

0

這是沒有意義的嘗試鎖定引用的數組到託管陣列。

那裏的引用值可能不會指向第一個元素的地址,即使他們這樣做了,那也是一個實現細節。它可能會從發佈到發佈。

將指針數組複製到大量數據中的速度不應該太慢,特別是與您正在調用的多媒體處理進行比較時。

如果有意義,請在託管堆以外分配數據,然後不進行固定或複製。但更多的簿記。

0

我所知道的最簡單的方法是使用一個維數組。它降低了複雜性,內存碎片並且還會有更好的性能。我其實在我的項目中這樣做。您可以使用手動索引,如array[i][j] = oneDimArray[i *n + j],並將n作爲參數傳遞給函數。你會做的只有一個固定就像你在你的例子做:

public void process(float[] oneDimInput, int numberOfColumns) 
{ 
    unsafe 
    { 
     fixed (float* inputPtr = &oneDimInput[0]) 
     { 
       // C function signature is someFuction(
       // float* input, 
       // int number of columns in oneDimInput 
       // int numberOfChannels, 
       // int length) 
       functionDelegate(inputPtr, numberOfColumns, 2, oneDimInput[0].length); 
     } 
    } 
} 

我也需要注意,二維數組很少在高性能計算庫,英特爾MKL,英特爾IPP和其他許多人使用。即使BLAS和Lapack接口只包含一個維度數組,並使用我剛纔提到的方法模擬兩個維度(出於性能原因)。

+0

這不回答這個問題。海報可能無法更改本機功能的簽名。 – Odrade

+0

如果可以的話,它會回答,而且這真的是最簡單的方法。原始答案中沒有信息,他是否可以。 –

+0

我實際上可以更改簽名,並且這個答案確實提示我考慮函數的簽名是否是最好的方法。雖然它沒有回答我問的問題,但它以某種方式幫助了我。 – Valdemar