LoginSignup
0
2

More than 3 years have passed since last update.

C++構造体メンバに対しC#クラスのプロパティでマーシャリングする

Last updated at Posted at 2020-10-12

メンバではなくプロパティでやる理由

C++の構造体に対しマーシャリングする時、通常ならメンバで充分対応出来るのですが
XMLやjsonへのシリアライズや、PropertyGridクラスへの対応が簡単に出来るようになるので
クラスのプロパティを使用します
(MSDNにプロパティとマーシャリングの関連について記述が見当たらなかったのでメモした具合です)

一例

睡眠限界状態なので色々省いてるかもです

C++側実装

C++
// 構造体定義
struct TestStruct
{
    int numA;
    int numB;
    wchar_t txt[20];
};

// 関数定義
extern "C" __declspec(dllexport) void CppDll(TestStruct test);

C#側実装

C#
// マーシャリング用クラス定義
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class TestStruct
{
    // メンバでやる方法
    int numA;

    // 公開プロパティにする
    // このプロパティはマーシャリングに影響しない
    public int numAProperty
    {
        get { return numA; }
        set { numA = value; }
    }

    /* ============================================ */

    // プロパティでやる方法
    // 自動プロパティで適用可
    public int numB { get; set; }

    /* ============================================ */

    // 文字列の場合
    // 自動プロパティは不可(後述)
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
    string txt;

    public string txtProperty
    {
        get { return txt; }
        set { txt = value; }
    }
}

// C++関数定義
[DllImport("hoge.dll")]
public static extern void CppDll(TestStruct test);

static void Main(string[] args)
{
    // 使用例
    var hoge = new TestStruct()
    {
        numAProperty = 1,
        numB = 2,
        txtProperty = "piyo",
    };
    CppDll(hoge);
}

MarshalAs属性が必要な場合は自動プロパティで対応出来ない

C#
// 以下エラーとなる
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string txt { get; set; }

MarshalAs属性が必要となるメンバに対しては指定不可なので
自動プロパティ以外の方法で実装する必要があります

最後に

寝る時間惜しんで書くもんでもなかった
C#でWM_COPYDATAを大量に使う事になるのが悪い

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2