2011-08-22 147 views
8

我想做到以下幾點:通多 - 從託管代碼維數組非託管代碼

  1. 這樣C#創建碼連續3個dimesinal陣列:

    var myArray = new short[x,y,z]; 
    UnanagedFunction(myArray); 
    
  2. 它傳遞給非託管代碼(C++)像這樣:

    void UnmanagedFunction(short*** myArray) 
    { 
        short first = myArray[0][0][0]; 
    } 
    

修訂 當我嘗試下面的代碼我有運行時錯誤:

Attempted to read or write to protected memory.

謝謝!

+0

你不能在C++中編寫這樣的代碼。 –

+0

代碼的第一部分是在C#第二部分是在C++中,我現在試過編譯器允許我的C代碼 –

+1

也許你可以改變你的代碼爲三元組數組。 – Simon

回答

7
IntPtr Array3DToIntPtr(short[, ,] Val) 
     { 
      IntPtr ret = Marshal.AllocHGlobal((Val.GetLength(0) + Val.GetLength(1) + Val.GetLength(2)) * sizeof(short)); 

      int offset = 0; 
      for (int i = 0; i < Val.GetLength(0); i++) 
      { 

       for (int j = 0; j < Val.GetLength(1); j++) 
       { 
        for (int k = 0; k < Val.GetLength(2); k++) 
        { 
         Marshal.WriteInt16(ret,offset, Val[i, j, k]); 
         offset += sizeof(short); 


        } 
       } 
      } 

      return ret; 
     } 

這已經過測試,它的工作原理,唯一的限制是,你必須在完成數組指針時調用Marshal.FreeHGlobal,否則將發生內存泄漏,我還建議您更改C++函數,以便它接受數組維數,否則您將只能使用特定的3d數組大小

+0

非常感謝! ! –

2

我在純C#中編寫它,但如果從Func中刪除unsafe staticFunc應該在C/C++中工作。要知道,我注意到肯定肯定是OK OK寫這個:-) 我使用這個Indexing into arrays of arbitrary rank in C#

static unsafe void Main(string[] args) { 
    var myArray = new short[5, 10, 20]; 

    short z = 0; 

    for (int i = 0; i < myArray.GetLength(0); i++) { 
     for (int j = 0; j < myArray.GetLength(1); j++) { 
      for (int k = 0; k < myArray.GetLength(2); k++) { 
       myArray[i, j, k] = z; 
       z++; 
      } 
     } 
    } 

    // myArray[1, 2, 3] == 243 

    fixed (short* ptr = myArray) { 
     Func(ptr, myArray.GetLength(0), myArray.GetLength(1), myArray.GetLength(2)); 
    } 
} 

// To convert to C/C++ take away the static unsafe 
static unsafe void Func(short* myArray, int size1, int size2, int size3) { 
    int x = 1, y = 2, z = 3; 
    int el = myArray[x * size2 * size3 + y * size3 + z]; // el == 243 
}