データをDLL(C++)からC#にマーシャリングして、データの受け渡しを行っているのですが、
動的配列を含む構造体をDLLからC#受け渡しする際、上手くマーシャリングが行かず、困っています。
C++
1struct A 2{ 3 int arrayLength; // 下記、動的配列(dArray)の長さ 4 DynamicArray* dArray; // newによるメモリ確保を使用し、動的配列として使用 5} 6 7struct DynamicArray 8{ 9 int arrayId; 10 float arrayVal; 11} 12 13// 構造体Aのデータ設定 14public void SetupA(A* a, int length) 15{ 16 a->arrayLength = length; 17 18 a->dArray = new DynamicArray[length]; 19 for(int idx = 0; idx < length; idx++) 20 { 21 a->dArray[idx].arrayId = idx; 22 a->dArray[idx].arrayVal = idx % 1.5f; 23 } 24}
上記の構造体をC#で以下のようにして、受け取ろうと考えています。
C#
1public struct A 2{ 3 int arrayLength; 4 DynamicArray[] dArray; 5 6 public void Setup(IntPtr ptr) 7 { 8 arrayLength = (int)Marshal.PtrToStructure(ptr, typeof(int)); 9 ptr += sizeof(int); 10 11 for(int idx = 0; idx < arrayLength; idx++) 12 { 13 dArray[idx].arrayId = (int)Marshal.PtrToStructure(ptr, typeof(int)); 14 ptr += sizeof(int); 15 16 dArray[idx].arrayVal = (float)Marshal.PtrToStructure(ptr, typeof(float)); 17 ptr += sizeof(float); 18 } 19 20 } 21} 22 23public struct DynamicArray 24{ 25 int arrayId; 26 float arrayVal; 27} 28 29// ptrには、DLLの受け取りたいAの先頭ポインタが入ります 30public void GetA(IntPtr ptr) 31{ 32 private A a = new A(); 33 a.Setup(ptr); 34}
可変配列部分が固定配列であれば、上手くいったのですが、
上記の形だと、arrayIdは正しく受け取ることができるのですが、
その下のdArrayから正しい数値を受け取ることができないようになってしまっております。
マーシャリングやC++自体不慣れでポインタ等の知識が不足している状態ですが、
何卒よろしくお願い致します。
《追記》
dArrayのそれぞれの要素の実体メモリ部分はnewで割り当てた別のところにあるのに、C#側でシーケンシャルなアクセスをしているからでは?というご指摘を頂き、恐らくこちらが原因だと思われます。
ただ、C#でunsafeを使うことで、ポインタを使用することができるとは思うのですが、Marshal.PtrToStructure()でポインタをマーシャリングする事ができませんでした。 もし、DLL側からポインタを受け取って、そのポインタを使用してその箇所の値にアクセスする手段がありましたら、ぜひご教授頂けないでしょうか?何卒、よろしくお願い致します。