構造体内に固定配列を持ったデータのやりとり
構造体内に固定配列を持ったデータを持っている場合 [MarshalAs(UnmanagedType.ByValArray, SizeConst=**配列のサイズ**)] を使います。
#include <windows.h> #include <cstddef> #include <iostream> using namespace std; #define DLLEXPORT __declspec(dllexport) WINAPI // ★C#側とC++側のデータの並びとサイズと一致させるためには、「pragma pack」の指定が必須 #pragma pack(1) struct TMyPicture { BYTE ColorDepth; int32_t Resolution[2]; bool HasAlpha; }; #pragma pack() // pragma pack は元へと戻った // 構造体受け取りと値の代入 extern "C" void DLLEXPORT dllStructPointer(TMyPicture *pMyPicture) { pMyPicture->Resolution[0] = 100; pMyPicture->Resolution[1] = 200; pMyPicture->ColorDepth = 32; pMyPicture->HasAlpha = true; }
using System; using System.Runtime.InteropServices; namespace test1 { internal class Program { [DllImport("Dll1.dll")] static extern void dllStructPointer(ref MyPicture pic); // この行を忘れないこと。原則Sequentialとして、Packも1とする [StructLayout(LayoutKind.Sequential, Pack=1)] struct MyPicture { public byte ColorDepth; // 固定配列で配列のサイズが2である [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)] public Int32[] Resolution; public bool HasAlpha; } static void Main(string[] args) { MyPicture pic = new MyPicture(); var structSize = Marshal.SizeOf(pic); Console.WriteLine(structSize); dllStructPointer(ref pic); Console.WriteLine($"{pic.Resolution[0]},{pic.Resolution[1]},{pic.ColorDepth},{pic.HasAlpha}"); Console.ReadKey(); } } }