none
DllImportでコールする関数の引数が構造体で、さらにその構造体内にbool型の変数があった場合 RRS feed

  • 質問

  • 下記のようなCPP側の関数をC#から呼び出すプログラムを作ったのですが、
    CPP側の関数の引数に、構造体を指定し、そのメンバをboolで作成した場合、
    C#側で、同じように構造体と関数を作成すると、実行時にCPPとC#で、引数の型が一致しないというエラーになってしまいました。

    不思議に思い、C#側の構造体のbool型のメンバを、すべてbyteで宣言し直し(中身はtrue/falseでは無く0,1と入れ直しましたが)
    関数を実行したところ、ちゃんと実行でき、また値も正しく渡っているようでした。

    DllImportで組み込んだ関数の構造体にboolがあるとうまくいかないのは何か制限がかかっているのでしょうか
    それとも宣言の仕方が悪いだけなのでしょうか

    関数の戻り値やただの引数にboolを指定するのは大丈夫なようなのですが・・・

    ●C++側
    typedef struct {
        bool bo1;
        bool bo2;
        bool bo2;
        int iNum;
    } CPPStruct

    int __stdcall foo(CPPSttuct cp);

    ●C#側
    //うまくいく構造体
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    private struct CSSTruct
    {
        public byte boVIS;
        public byte boIR;
        public byte boUV;
        public int iNum;
    }

    //失敗する構造体
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    private struct CSSTruct
    {
        public bool boVIS;
        public bool boIR;
        public bool boUV;
        public int iNum;
    }


    [DllImport("testdll.dll", EntryPoint = "foo")]
    private static extern int foo(CSSTruct st);
    private void int fooWrap()
    {
     int iRt;
     CSSTruct cst;
     //cstに適当な値を代入

     iRt = foo(cst);
    }

    2011年10月13日 8:56

回答

  • C++ の bool 型は通常 1byte データです(※処理系依存)。

    C# の bool 型は、DllImport 下ではマーシャラは特に指示がなかった場合 Win32API における BOOL 型、つまり 4byte 整数として変換されます。

    どう変換するかは、MarshalAs 属性で指定できます。

    • 回答の候補に設定 山本春海 2011年11月1日 8:50
    • 回答としてマーク 山本春海 2011年11月2日 8:21
    2011年10月13日 9:25