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

来源:互联网 发布:app数据录入 编辑:程序博客网 时间:2024/05/16 12:23

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

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

        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()也应该可以,没有做实验

 



原创粉丝点击