個人的に用いる目的で、UnityのC#からバックエンドのC++のDLLを呼び出すプログラムを作っています。プラットフォームはwindowsのみを想定しています。
通常、そのような場合C#側では
C#
1[DllImport("HogeLib")] 2extern void Hoge(IntPtr ptr); 3 4void test() 5{ 6 double[] x = new double[10] 7 var handle = GCHandle.Alloc(x, GCHandleType.Pinned); 8 IntPtr ptr = handle.AddrOfPinnedObject(); 9 Hoge(ptr); 10 handle.Free(); 11}
としてネイティブDLLを呼び出すのが正しい方法かと思うのですが、一部のサイト等では単に
C#
1[DllImport("HogeLib")] 2extern void Hoge(double[] ptr); 3 4void test() 5{ 6 double[] x = new double[10]; 7 Hoge(x); 8}
としているような例を見かけました。
これだとDLL呼び出し中にガベージコレクションでxのアドレスが変わった場合問題が起きるので、
これが良くないのは分かるのですが、
C#
1[DllImport("HogeLib")] 2extern void Hoge(double[] ptr); 3 4void test() 5{ 6 double[] x = new double[10]; 7 var handle = GCHandle.Alloc(x, GCHandleType.Pinned); 8 Hoge(x); 9 handle.Free(); 10}
とするのは何か問題があるんでしょうか?
これまで、この方法でdoubleやintの配列をネイティブDLLに渡して要素の値を書き換えても特に問題は起きなかったのですが、自作の構造体の配列を同じ方法でDLLに渡すと要素の値は受け取れるものの、DLL内で要素の値を書き換えてもC#側には反映されませんでした。
構造体は以下のようなintとdoubleを並べただけの単純なものです。
C#
1struct MyStruct 2{ 3 int i1; 4 double a1; 5 double a2; 6 double a3; 7 double a4; 8 double a5; 9}
なぜdouble[]を渡した場合はDLL内での要素値の書き換えが反映されて、MyStruct[]では書き換わらないのでしょうか?
試したこと
一番上に書いた方法を用いれば、プログラムは問題なく動作しています。
ただ、引数を全てIntPtrにしてしまうとDLLの引数がIntPtrだらけになり可読性が悪くなるのと、型チェックが働かなくなるため、できればdouble[]やMyStruct[]等の形で渡したいと思った次第です。
補足情報
・Windows 10
・Visual Studio 2015 update3
・Unity 2017.4.1
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/08 15:07