Marshal.SizeOf是如何计算大小的

这篇文章主要讲解了“Marshal.SizeOf是如何计算大小的”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Marshal.SizeOf是如何计算大小的”吧!

目前创新互联公司已为数千家的企业提供了网站建设、域名、网页空间、绵阳服务器托管、企业网站设计、台安网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

今天发现一个C#的怪现象:
string[] msgs = { "zs", "li", "wu" };
int sizeoflen = Marshal.SizeOf(msgs);
IntPtr pmsgs = Marshal.AllocHGlobal(sizeoflen);
结果发现Marshal.SizeOf(msgs)这一句出现:ArgumentException类型的未经处理的异常在mscorlib.dll中发生,其它信息:String[]不能作为非托管结构进行封送处理:无法计算有意义的大小或偏移量。如何换成int sizeoflen = Marshal.SizeOf(msgs[0]);也是异常:String不能作为非托管结构进行封送处理:无法计算有意义的大小或偏移量。
但是如果有:
[StructLayout(LayoutKind.Sequential)]
        class CLS
        {
            public int id;
            public float value;
            [MarshalAs(UnmanagedType.ByValArray,SizeConst=10,ArraySubType=UnmanagedType.Struct)]
            public Point[] ps;
            [MarshalAs(UnmanagedType.LPStr)]
            public string msg;
            [MarshalAs(UnmanagedType.ByValArray,SizeConst=5,ArraySubType=UnmanagedType.LPStr)]
            public string[] msgs;
        }
CLS[] clss = new CLS[2];
int clsslen = Marshal.SizeOf(clss);
也是出现类似上面的CLS[]异常;修改为
int clsslen = Marshal.SizeOf(clss[0]);则出现:AugumentNullException类型的未经处理的异常:值不能为null。再次修改为 
clss[0] = new CLS();
clss[1] = new CLS();
int clsslen = Marshal.SizeOf(clss);还是出现:CLS[]异常;再修改为针对一个成员对象:
int clsslen = Marshal.SizeOf(clss[0]);则成功出现值大小。
这说明要想计算CLS[] clss的真正大小,可以用一个成员的大小再乘以元素数量。
回到最开始的string[] msgs = { "zs", "li", "wu" };上来说,最终实验发现不管是用Marshal.SizeOf(msgs)还是用Marshal.SizeOf(msgs[0])都是无法计算大小的异常。由此可以总结出来:
string或string[]要想计算大小,是不可能通过Marshal.SizeOf来得到结果的。
其它的包括struct值类型(struct需要StructLayout属性进行限定)在内是可以通过Marshal.SizeOf获得大小的,基础值类型可以用sizeof获得;引用类型则可以通过Marshal.SizeOf获得,但数组不能直接获得,需要先初始化数组的成员,然后Marshal.SizeOf(一个成员对象变量)的结果再乘以数组长度就是总内存大小。

感谢各位的阅读,以上就是“Marshal.SizeOf是如何计算大小的”的内容了,经过本文的学习后,相信大家对Marshal.SizeOf是如何计算大小的这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!


网站栏目:Marshal.SizeOf是如何计算大小的
本文网址:http://hbruida.cn/article/ppcppg.html