5

これらのフィールドに名前を付けて申し訳ありませんが、NDAに基づいてフィールド名などをブロックする必要があります。

つまり、基本的に私はC#を使用しており、Interopを使用して外部ライブラリと通信しています。外部ライブラリでは、特定の構造を参照で渡す必要があり、そのうちの1つはユニオンを使用します。これは私に頭痛の種を与えているように見える構造体です。2つのデータ型を結合する方法についてオンラインでいくつかの参照を見つけましたが、2つの構造体を一緒に結合することはできません。これが2つの構造体の基本です

struct datatype1
{ 
    char field1; 
    char field2; 
    char field3;
    char field4;
    char field5; 
    char field6; 
    char field7; 
};

struct datatype2
{
    public uint field8;
    public uint field9;
}

struct datatype3
{
    unsigned int field10;
    union
    {
        datatype1 field11;
        datatype2 field12;
    } field13;
    uint field14;
    unsigned char field15;
    uint field16;
}

結果の構造体はC#でどのようになりますか?私はいくつかのアイデアを持っていましたが、そのうちのいくつかは機能しているように見えますが、しばらくするとreference_by_pointerのメッセージが表示された青い画面になります。構造体の定義に関する何かが間違っている可能性があり、どういうわけかデータが適合していないと考えていました。構造体で正しく。これが私が現在持っているものです:

    [StructLayout( LayoutKind.Sequential )]
    public struct datatype1
    {
        public byte field1;
        public byte field2;
        public byte field3;
        public byte field4;
        public byte field5;
        public byte field6;
        public byte field7;
    }

    [StructLayout( LayoutKind.Sequential )]
    public struct datatype2
    {
        public uint field8; // Digital i/p event
        public uint field9;
    }

    public struct datatype3
    {
        public uint field10;

        [StructLayout( LayoutKind.Explicit )]
        public struct AnonymousStruct
        {
            [FieldOffset( 0 )]
            public datatype1 field11;

            [FieldOffset( 0 )]
            public datatype2 field12;
        }

        public AnonymousStruct field13;

        public uint field14;

        public byte[] field15;

        public uint field16;
    }

私はこれをすべて間違っていますか?

編集:詳細情報のリクエストに応えて、ここに使用例がありますが、APIに隠されているため、フィールドの母集団を提供できないわけではありません。

また、APIに問題がある可能性もありますが、それは私が相互運用機能を台無しにするよりもありそうにありません。

    ...inside thread....
    datatype3 dt = new datatype3();
    while( true )
    {
        api.get_next_value( ref dt );
        PrintData( dt );
        Thread.Sleep( 55 );
    }


    /// <summary>
    /// Prints the data from the event.  Used for debugging purposes.
    /// </summary>
    /// <param name="evp"></param>
    private void PrintData( datatype3 evp )
    {
        if( evp.field10 == 2 )
        {
            Console.WriteLine( "datatype2" );
            Console.WriteLine( "\tfield8val: " + evp.field13.field12.field8);
            Console.WriteLine( "\tfield9val: " + evp.field13.field12.field9 );
        }
        else if( evp.de_type == 1 )
        {
            Console.WriteLine( "datatype1" );
            Console.WriteLine( "\tfield1val:  " + evp.field13.field12.field1 );
            Console.WriteLine( "\tfield2val:  " + evp.field13.field12.field2 );
            Console.WriteLine( "\tfield3val:  " + evp.field13.field12.field3 );
            Console.WriteLine( "\tfield4val:  " + evp.field13.field12.field4 );
            Console.WriteLine( "\tfield5val:  " + evp.field13.field12.field5 );
            Console.WriteLine( "\tfield6val:  " + evp.field13.field12.field6 );
            Console.WriteLine( "\tfield7val:  " + evp.field13.field12.field7 );
        }
        else
        {
            return;
        }
    }

絶対的な電話や真のコンテキストを提供できなかったことをお詫びしますが、回答の質を低下させることを意味する場合でも、NDAを尊重する必要があります。

編集2:一緒に結合されている2つの異なるサイズのデータ​​型がこの状況に影響を及ぼしている可能性はありますか?datatype1のサイズは7バイトで、datatype2のサイズは8バイトです。これはある種のメモリの問題を引き起こす可能性がありますか?

4

1 に答える 1

4

C# ユニオンに問題はありません。しかし、field15間違っています。それcharは C コードとbyte[]C# コードにあります。byteC# コードのように宣言する必要があります。

LayoutKind.Sequential構造体のデフォルトであるため、省略しても安全です。

于 2013-01-07T21:04:02.813 に答える