Пример #1
0
 static void Main(string[] args)
 {
     #region MyFuncA intを渡す
     int ans = MyFuncA(1);
     Console.WriteLine(ans);
     #endregion
     #region MyFuncB char[]を渡す
     MyFuncB(2, "call MyFuncB from C#");
     #endregion
     #region MyFuncC char[]を渡して操作させる
     StringBuilder sb = new StringBuilder(256);
     MyFuncC(3, sb);
     //領域不足だとAccessViolationException
     //MyFuncC(4, new StringBuilder(4));
     #endregion
     #region MyFuncD 構造体を渡す
     //渡す構造体の初期化
     var st = new SampleStruct()
     {
         index = 4,
         name  = "構造体サンプル",
         data  = new int[50],
     };
     st.data[0] = 10;
     st.data[1] = 20;
     st.data[2] = 30;
     MyFuncD(st);
     #endregion
     #region MyFuncE 構造体を渡して操作させる
     var pst = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SampleStruct)));
     try
     {
         MyFuncE(pst);
         var st_rtn = (SampleStruct)Marshal.PtrToStructure(pst, typeof(SampleStruct));
         Console.WriteLine($"index = {st_rtn.index}");
         Console.WriteLine($"name = {st_rtn.name}");
         Console.WriteLine(($"data = [{st_rtn.data[0]},{st_rtn.data[1]},{st_rtn.data[2]}]"));
     }
     catch (Exception e)
     {
         System.Diagnostics.Debug.WriteLine(e);
     }
     finally
     {
         //必ずメモリ解放
         Marshal.FreeHGlobal(pst);
     }
     #region 参照型の参照渡し・・・正常終了するが値がセットされない
     Console.WriteLine("MyFuncE(参照型を渡すパターン)");
     SampleStructClass stc = new SampleStructClass();
     MyFuncE(stc);
     Console.WriteLine($"index = {stc.index}");
     Console.WriteLine($"name = {stc.name}");
     //Console.WriteLine($"data = {stc.data[0]}, {stc.data[1]}, {stc.data[2]}");
     #endregion
     #endregion
     #region MyFuncF ポインタを含む構造体を渡す
     var pst2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SampleStruct2)));
     try
     {
         MyFuncF(pst2);
         var st2 = (SampleStruct2)Marshal.PtrToStructure(pst2, typeof(SampleStruct2));
         for (var i = 0; i < st2.length; i++)
         {
             var v = Marshal.ReadInt64(st2.data, i * sizeof(double));
             Console.WriteLine($"data[{i}] = {BitConverter.Int64BitsToDouble(v)}");
         }
     }catch (Exception e)
     {
         System.Diagnostics.Debug.WriteLine(e);
     }
     finally
     {
         Marshal.FreeHGlobal(pst2);
     }
     #endregion
     #region MyFuncG intのポインタを渡す
     int g = 0;
     Console.WriteLine(g);
     MyFuncG(ref g);
     #endregion
     #region MyFuncH intのポインタのポインタを渡す
     unsafe
     {
         int   h   = 0;
         int * pt1 = &h;
         int **pt2 = &pt1;
         Console.WriteLine(**pt2);
         MyFuncH(pt2);
     }
     #endregion
     #region MyFuncI 構造体SampleStructのポインタのポインタを渡す
     var pst3 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SampleStruct)));
     try
     {
         MyFuncI(ref pst3);
         var st_rtn = (SampleStruct)Marshal.PtrToStructure(pst3, typeof(SampleStruct));
         Console.WriteLine($"index = {st_rtn.index}");
         Console.WriteLine($"name = {st_rtn.name}");
         Console.WriteLine(($"data = [{st_rtn.data[0]},{st_rtn.data[1]},{st_rtn.data[2]}]"));
     }
     catch (Exception e)
     {
         System.Diagnostics.Debug.WriteLine(e);
     }
     finally
     {
         //必ずメモリ解放
         Marshal.FreeHGlobal(pst);
     }
     #endregion
     Console.ReadKey();
 }
Пример #2
0
 private static extern void MyFuncE(SampleStructClass st); //参照型を渡すパターン:NG