構造体の構造体を使ったデータのやりとり
構造体の構造がネストしていたとしても、特に関係はありません。 データ構造をC#とC++で一致させていればよいだけです。 C++側の#pragma pack(1)の指定と、[StructLayout(LayoutKind.Sequential, Pack=1)] その点を気をつけましょう。
#include <windows.h> #include <cstddef> #include <iostream> using namespace std; #define DLLEXPORT __declspec(dllexport) WINAPI // ★C#側とC++側のデータの並びとサイズと一致させるためには、「pragma pack」の指定が必須 #pragma pack(1) struct TPicResolution { int32_t Width; int32_t Height; }; struct TMyPicture { BYTE ColorDepth; TPicResolution Resolution; bool HasAlpha; }; #pragma pack() // pragma pack は元へと戻った // 構造体受け取りと値の代入 extern "C" void DLLEXPORT dllStructPointer(TMyPicture *pMyPicture) { pMyPicture->Resolution.Width = 100; pMyPicture->Resolution.Height = 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 TMyPicture pic); // この行を忘れないこと。原則Sequentialとして、Packも1とする [StructLayout(LayoutKind.Sequential, Pack = 1)] struct TPicResolution { public Int32 Width; public Int32 Height; } // この行を忘れないこと。原則Sequentialとして、Packも1とする [StructLayout(LayoutKind.Sequential, Pack=1)] struct TMyPicture { public byte ColorDepth; public TPicResolution Resolution; public bool HasAlpha; } static void Main(string[] args) { TMyPicture pic = new TMyPicture(); var structSize = Marshal.SizeOf(pic); Console.WriteLine(structSize); dllStructPointer(ref pic); Console.WriteLine($"{pic.Resolution.Width},{pic.Resolution.Height},{pic.ColorDepth},{pic.HasAlpha}"); Console.ReadKey(); } } }