美文网首页
[C#-Windows]解决 C# 中使用联合体的问题(因为它在

[C#-Windows]解决 C# 中使用联合体的问题(因为它在

作者: storyteller_F | 来源:发表于2021-03-23 22:17 被阅读0次

    [C#-Windows]解决 C# 中使用联合体的问题(因为它在0偏移位置处包含一个对象字段...)

    问题

    开发的程序会使用到Windows api,因为在C 中开发图形界面程序有点麻烦,所以改为了C# ,但是这个api 里有一个数据是以联合体存储的,C# 的联合体又有一些限制。

    public struct Anonymous_d34c77ee_53b2_47a5_a97c_d5c2b29c8ee3 {
    
        /// RAWMOUSE->tagRAWMOUSE
        [System.Runtime.InteropServices.FieldOffset(0)]
        public TagRAWMOUSE mouse;
    
        /// RAWKEYBOARD->tagRAWKEYBOARD
        [System.Runtime.InteropServices.FieldOffset(0)]
        public TagRAWKEYBOARD keyboard;
    
        /// RAWHID->tagRAWHID
        [System.Runtime.InteropServices.FieldOffset(0)]
        public TagRAWHID hid;
    }
    
    

    产生的错误的信息是

    ...因为他在0偏移位置处包含一个对象字段,该字段由一个非对象字段不正确地对齐或重叠。

    经过测试,联合体如果都是一些简单类型,比如整形之类的,就没有问题。如果是这种复杂类型,就不行。

    解决

    耽搁了很长时间,一直想不到解决办法,有一天,突然开窍了,我把整个结构体拆成三个正常的、没有联合体地结构体不就行了,反正是操作那一片地址,如何解释还不是我说了算吗。

    //原本长这样
    public struct TagRAWINPUT {
    
        /// RAWINPUTHEADER->tagRAWINPUTHEADER
        public TagRAWINPUTHEADER header;
    
        /// Anonymous_d34c77ee_53b2_47a5_a97c_d5c2b29c8ee3
        public Anonymous_d34c77ee_53b2_47a5_a97c_d5c2b29c8ee3 data;
    }
    //改成这样
    public struct TagRAWINPUTONE {
        public TagRAWINPUTHEADER header;
    }
    

    仅通过后面的header就能够了解后面的联合体具体存储地是哪一个数据,是mouse,还是keyboard,还是hid。

    //原本
    TagRAWINPUT rawInput = Marshal.PtrToStructure<TagRAWINPUT>(dataBuffer);
    //新的
    TagRAWINPUTONE rawInputOne = Marshal.PtrToStructure<TagRAWINPUTONE>(dataBuffer);
    

    因为TagRAWINPUTONE 没有联合体,所以这段代码执行没有任何问题。根据header 判断联合体的类型,然后在通过Marshal 获取真正的结构体。

    比如这个联合体存储的是TagRAWMOUSE ,那就把结果转换成TagRAWINPUT1

    //另外两个以此类推
    public struct TagRAWINPUT1 {
    
        /// RAWINPUTHEADER->tagRAWINPUTHEADER
        public TagRAWINPUTHEADER header;
    
        /// Anonymous_d34c77ee_53b2_47a5_a97c_d5c2b29c8ee3
        public TagRAWMOUSE mouse;
    }
    
    TagRAWINPUT1 raw = Marshal.PtrToStructure<TagRAWINPUT1>(dataBuffer);
    

    相关文章

      网友评论

          本文标题:[C#-Windows]解决 C# 中使用联合体的问题(因为它在

          本文链接:https://www.haomeiwen.com/subject/owpqhltx.html