「ライブラリの基礎 - C++DLL」の版間の差分

ナビゲーションに移動 検索に移動
98行目: 98行目:
     int data[50];
     int data[50];
  } SampleStruct, *pSampleStruct;
  } SampleStruct, *pSampleStruct;
typedef struct tagSampleStruct2
{
    int length;
    double *data;
} SampleStruct2, *pSampleStruct2;
   
   
  double __stdcall SampleFunc01(int a)
  double __stdcall SampleFunc01(int a)
129行目: 135行目:
     printf("name = %s\r\n", st.name);
     printf("name = %s\r\n", st.name);
     printf("data[0] = %d, data[1] = %d, data[2] = %d, data[3] = %d\r\n", st.data[0], st.data[1], st.data[2], st.data[3]);
     printf("data[0] = %d, data[1] = %d, data[2] = %d, data[3] = %d\r\n", st.data[0], st.data[1], st.data[2], st.data[3]);
    printf("------------------------\r\n");
}
void __stdcall SampleFunc05(SampleStruct2 *pStructure)
{
    dData[256] = {0};
    printf("--<SampleDll:Sample05>--\r\n");
    memset(pStructure, 0, sizeof(SampleStruct2));
    pStructure->length = 10;
    pStructure->data = dData;
    for(int i = 0; i < pStructure->length; i++)
    {
      dData[i] = (i + 1) / 10.0;
    }
     printf("------------------------\r\n");
     printf("------------------------\r\n");
  }
  }
143行目: 163行目:
           SampleFunc03  @3
           SampleFunc03  @3
           SampleFunc04  @4
           SampleFunc04  @4
          SampleFunc05  @5
  </source>
  </source>
<br>
<br>
155行目: 176行目:
  <source lang="c#">
  <source lang="c#">
  using System;
  using System;
using System.Text;
  using System.Runtime.InteropServices;
  using System.Runtime.InteropServices;
   
   
177行目: 199行目:
       private static extern void SampleFunc03(int a, StringBuilder str);
       private static extern void SampleFunc03(int a, StringBuilder str);
   
   
        /// <summary>
      /// <summary>
        /// 構造体を引数に持つ関数のインポート例
      /// 構造体を引数に持つ関数のインポート例
        /// </summary>
      /// </summary>
        /// <param name="st">DLL 側に渡す構造体を指定します</param>
      /// <param name="st">DLL 側に渡す構造体を指定します</param>
        [DllImport("Tips_Win32DLL.dll")]
      [DllImport("SampleDLL.dll")]
        private static extern void Sample04(SampleStruct st);
      private static extern void SampleFunc04(SampleStruct st);
      /// <summary>
      /// DLL側からメンバにポインタを含む構造体を受け取る関数のインポート例
      /// </summary>
      /// <param name="pst">受け渡す構造体の先頭アドレスを示すポインタを指定する</param>
      [DllImport("SampleDLL.dll")]
      private static extern void SampleFunc05(IntPtr pst);
   
   
        /// <summary>
      /// <summary>
        /// DLLとの取り合いのために定義する構造体
      /// DLLとの取り合いのために定義する構造体
        /// LayoutKind.Sequentialを指定することで、C/C++同様、変数の宣言順通りにメモリに配置されるようになる
      /// LayoutKind.Sequentialを指定することで、C/C++同様、変数の宣言順通りにメモリに配置されるようになる
        /// </summary>
      /// </summary>
        [StructLayout(LayoutKind.Sequential)]
      [StructLayout(LayoutKind.Sequential)]
        private struct SampleStruct
      private struct SampleStruct
        {
      {
          /// <summary>
          /// <summary>
          /// 4バイト符号付整数
          /// 4バイト符号付整数
          /// </summary>
          /// </summary>
          [MarshalAs(UnmanagedType.I4)]
          [MarshalAs(UnmanagedType.I4)]
          public int index;
          public int index;
   
   
          /// <summary>
          /// <summary>
          /// 固定長文字配列(SizeConstは配列のサイズを示す)
          /// 固定長文字配列(SizeConstは配列のサイズを示す)
          /// </summary>
          /// </summary>
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
          public string name;
          public string name;
   
   
          /// <summary>
          /// <summary>
          /// 固定長配列(SizeConstは配列の要素数を示す)
          /// 固定長配列(SizeConstは配列の要素数を示す)
          /// </summary>
          /// </summary>
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
          [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
          public int[] data;
          public int[] data;
        }
      }
   
   
      /// <summary>
      /// DLLとの取り合いのために定義する構造体
      /// LayoutKind.Sequentialを指定することで、C/C++同様、変数の宣言順通りにメモリに配置されるようにする
      /// </summary>
      [StructLayout(LayoutKind.Sequential)]
      private struct SampleStruct2
      {
          public int length;
          public IntPtr data;
      }
 
       static void Main(string[] args)
       static void Main(string[] args)
       {
       {
235行目: 275行目:
           structHoge.data[2] = 33;
           structHoge.data[2] = 33;
           SampleFunc04(structHoge);
           SampleFunc04(structHoge);
          var structPiyo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SampleStruct2)));
          try
          {
            SampleFunc05(structPiyo);
            var structFuga = (SampleStruct2)Marshal.PtrToStructure(structPiyo, typeof(SampleStruct2));
            for (int i = 0; i < structFuga.length; i++)
            {
                var v = Marshal.ReadInt64(structFuga.data, i * sizeof(double));
                Console.WriteLine("data[{0}] = {1}", i, BitConverter.Int64BitsToDouble(v));
            }
          }
          catch (Exception ex)
          {
            System.Diagnostics.Debug.WriteLine(ex);
          }
          finally
          {
            // 必ずメモリを解放する
            Marshal.FreeHGlobal(sample06_a);
          }
   
   
           Console.ReadKey();
           Console.ReadKey();

案内メニュー