C# 固定大小结构体的几种测试

49 篇文章 0 订阅

如果高手路过,请帮忙解决下

想要实现一个具有固定大小的结构体,如下所示:

        struct Info
        {
            public char name[16];
            public char cipher[16];
            public char signature[256];
        }
(1) 测试一

用fixed关键字和Mashal类来实现

1>结构的声明

在C#中,数组是引用对象,属于托管对象;而我要实现的则是非托管对象,为防止分配的内存被垃圾回收机制回收掉,所以用fixed关键字来盯住

声明如下:

        unsafe struct Info
        {
            public fixed char name[16];
            public fixed char cipher[16];
            public fixed char signature[256];
        }
2>结构的赋值

char name[16]在C#中认为是一个char* ,即字符指针,属于非托管对象;string属于托管对象;两者之间相互转换需要用到Marshal类的方法进行转换

            char* pName=myInfo.name;
            pName=(char* )Marshal.StringToBSTR("abcd");
问题就出在:            char* pName=myInfo.name;

问题:调试的时候发现,pName是有值的,而myInfo.name仍然非空。

原因:两者并未指向同一内存区域

解决办法:尚未知

(2) 测试二

用MarshalAsAttribute类与MarshalAs来实现托管对象对非托管对象的模拟

这个方法不用在unsafe环境中编译

[MarshalAs()]可以实现一个MarshalAsAttribute类的对象

用法:[MarshalAs(UnmanagedType, 命名参数)]

当需要实现固定大小的字符数组时,UnmanagedType 设置为 ByValArray时,并设置 SizeConst 以指示数组中的元素数;

代码如下:

        struct Info
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public char[] name;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public char[] cipher;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
            public char[] signature;
        }

使用的时候也可以按正常的char[]使用

            Info myInfo;
            string name = "abcd";
            myInfo.name = name.ToCharArray();
            string cipher = "1234";
            myInfo.cipher=cipher.ToCharArray();
            string signature = "it is a new test";
            myInfo.signature = signature.ToCharArray();
注意:在上述赋值语句中,myInfo.name 等的大小是string name的大小,即其大小不足16,导致了如下问题:

因为我有一个特殊的需要,把该结构体转为byte[]型,出了点问题。提示如下错误:嵌入数组实例的长度与布局中声明的长度不匹配。

改进

字符串string有一个方法PadLeft()/PadRight(),这两个方法能够将字符串填充为固定大小的字符串

函数如下:

 
 PadRight(Int32)  左对齐此字符串中的字符,在右边用空格填充以达到指定的总长度。 
PadRight(Int32, Char)  左对齐此字符串中的字符,在右边用指定的 Unicode 字符填充以达到指定的总长度。 
注意:该方法可以返回一个新的string,而不会改变调用该方法的string
改进之后的赋值如下:

            Info myInfo;
            string name = "abcd";
            myInfo.name = name.PadRight(16).ToCharArray();
            string cipher = "1001593";
            myInfo.cipher=cipher.PadRight(16).ToCharArray();
            string signature = "it is a new test";
            myInfo.signature =signature.PadRight(256).ToCharArray() ;

这次再进行结构与byte[]的转换就没有问题了,成功!

引申

同样的,用string的方法copyto()也应该可以,没有做实验

 



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值