72789


電文を構造体に変換するのに共用体を使用して上手く行かないのでどなたか助けてください  
C言語のように気軽に考えていたのですが、どうも同じような考えではダメなようです

単純に構造体に入っている値を共用体を経由して配列に渡したいだけです

こちらのサンプルはheadと言う変数の内容をuni.headにコピーするだけですがそこでクラッシュし、プログラムが停止します  
そのさい、catchにも移動せずにプログラムが停止します  
同じ型のhead2にコピーするのは成功しています  
uni.head内のメンバ変数に単純に値を代入するのも同様にプログラムが停止します

変換関数を真面目に書けばいいだけなのですが、この様な共用体の挙動について何故こうなるのか教えていただければと思います

[code]

    /// <summary>
    /// 電文構造体 ヘッダ
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct TMsgHead
    {
        public ushort a;
        public ushort b;
        public byte c;
        public byte d;
        public byte rsv1;
        public byte rsv2;
    }
    
    /// <summary>
    /// 変換用構造体
    /// </summary>
    [StructLayout(LayoutKind.Explicit)]
    public struct TMsgHeadUnion
    {
        [FieldOffset(0)] public TMsgHead head;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] 
        [FieldOffset(0)] public byte[] Hairetsu;
    }
    
    /// <summary>
    /// ボタンでテスト
    /// </summary>
    private void Button_Clicked(object sender, EventArgs e)
    {
        TMsgHead head = new TMsgHead();
        TMsgHead head2;
        
        head.a = 1;
        head.b = 2;
        head.c = 3;
        head.d = 4;
    
        TMsgHeadUnion uni = new TMsgHeadUnion();
        uni.head = new TMsgHead();
        try
        {
            head2 = head;       //★コピー成功する
            uni.head = head;    //★エラーになり、catchにも飛ばない、プログラム停止
        }catch(Exception ex)
        {
            string str = ex.ToString();
        }
        uni.head.a = 3;         //★エラーになり、プログラム停止
        uni.Hairetsu = new byte[8];
        byte[] t = new byte[8];
        Array.Copy(uni.Hairetsu, t, 8);
    }
    
[/code]


CC BY-SA 4.0
2020-12-20T15:16:41.987
72774
2020-12-21T06:23:21.710
2020-12-20T16:31:12.163
3060
10098
question
c# xamarin xamarin.forms
Xamarin.Formsで共用体のコピーに失敗する


[c#](/questions/tagged/c%23 "'c#' のタグが付いた質問を表示") の「配列」は参照型なので、提示
`TMsgHeadUnion` は [c](/questions/tagged/c "'c' のタグが付いた質問を表示") 流に書くと

[code]

    union TMsgHeadUnion {
        TMsgHead head;
        byte* Hairetsu; // byte Hairetsu[8] ではない
    };
    
[/code]

になります。あなたのやりたいこととは異なっている可能性が高いです。具体的に何をどうしたいのか微妙に想像つきませんが、素直に変換関数を書くほうがよさそうな気がします。

[c](/questions/tagged/c "'c' のタグが付いた質問を表示") でも通信電文（バイトの列）を `union`
を使って複数バイト型に直接変換しようとするとエンディアン問題が発生しますので異 CPU
への移植性がなくなります。（組み込み系ではコストダウンでマイコン変更を行うことがあります）エンディアネスにべたべたに依存するコードは書かないほうが良いでしょう。


CC BY-SA 4.0
2020-12-21T06:23:21.710
72789
2020-12-21T06:23:21.710
8589
72774
answer