構造体の構造体

概要

構造体の構造体を使ったデータのやりとり

構造体の構造体

構造体の構造がネストしていたとしても、特に関係はありません。
データ構造をC#とC++で一致させていればよいだけです。
C++側の#pragma pack(1)の指定と、[StructLayout(LayoutKind.Sequential, Pack=1)]
その点を気をつけましょう。

  • C++側のソース

    Dll1.dllとしてコンパイル
    #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;
    }
    
  • C#側のソース

    test1.cs
    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();
            }
        }
    }