やりたいこと
String型配列の内容をMarshall、GCHandleを用いてstringだけで構成されている構造体に格納したいです。
例
以下のようなTest構造体、string型配列inputがあります。このstring型配列inputの内容をMarshall、GCHandleを用いて構造体に格納し、最終的な動作のようになりたいです。
c#
1//Test構造体 2public struct Test 3 { 4 public string x; 5 public string y; 6 public string z; 7 //配列の大きさは2 8 public test1[] test1s; 9 } 10 public struct test1 11 { 12 public string e; 13 } 14//input 15string[] input= new string[5] { "1", "2", "3","4","5" }; 16 17//最終的な動作 18Test.x = "1"; 19Test.y = "2"; 20Test.z = "3"; 21Test.test1[0].e = "4"; 22Test.test1[1].e = "5"; 23
現在ためしたこと
以下のようなソースを作成し、実行しました。結果として、Main関数内の
GCHandle gch = GCHandle.Alloc(a, GCHandleType.Pinned)でエラーが発生しました
(エラー内容はソースの下にあります)。
c#
1 using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6using System.IO; 7using System.Runtime.InteropServices; 8 9 10namespace ConsoleApp2 11{ 12 class Program 13 { 14 [StructLayout(LayoutKind.Sequential)] 15 public struct Test 16 { 17 [MarshalAs(UnmanagedType.BStr)] 18 public string x; 19 [MarshalAs(UnmanagedType.BStr)] 20 public string y; 21 [MarshalAs(UnmanagedType.BStr)] 22 public string z; 23 //配列の大きさは2 24 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 25 public test1[] test1s; 26 } 27 public struct test1 28 { 29 [MarshalAs(UnmanagedType.BStr)] 30 public string e; 31 } 32 33 static void Main(string[] args) 34 { 35 try 36 { 37 //input,Testの実体生成 38 string[] input = new string[5] { "1", "2", "3","4","5"}; 39 Test test = new Test(); 40 test.test1s = new test1[2]; 41 42 //inputを構造体に格納 43 GCHandle gch = GCHandle.Alloc(input, GCHandleType.Pinned); 44 Test result = (Test)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(Test)); 45 gch.Free(); 46 } 47 catch (Exception e) 48 { 49 Console.WriteLine(e.Message); 50 } 51 52 53 } 54 } 55} 56
//エラー内容 Object contains non-primitive or non-blittable data. (Parameter 'value')
上記のエラーを調べ、UnmanagedTypeを変更するという対処を実施しても解決しなかったです。
例で示した、最終的な動作と同様の結果を得るには、どのように修正すればよろしいでしょうか?
お忙しい中恐縮ですが、どなたかご助言いただけますと幸いです。
構造体うんぬんは関係ありません。どこでエラーが発生しているか、デバッグしてみましょう。
構造体のコンストラクタに配列を渡すようにすれば事足りるはずです。