关于[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] 的解释

发布时间:2024-11-28 02:03

相机设置中关于色彩温度的解释 #生活技巧# #数码产品使用技巧# #相机设置解析#

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]

这是C#引用非托管的C/C++的DLL的一种定义定义结构体的方式,主要是为了内存中排序,LayoutKind有两个属性Sequential和Explicit

Sequential表示顺序存储,结构体内数据在内存中都是顺序存放的Explicit表示精确布局,需要用FieldOffset()设置每个成员的位置这都是

为了使用非托管的指针准备的,知道什么意思就行,C#的CLR提供了更为灵活的自动管理方式,所以对C#来说可有可无。

CharSet=CharSet.Ansi表示编码方式

http://blog.csdn.net/masterft/article/details/1699009

http://www.cnblogs.com/lonelyDog/archive/2012/02/02/2335432.html

http://www.cnblogs.com/namek/archive/2010/08/26/1808773.html

1.Sequential,顺序布局,比如
struct S1
{
int a;
int b;
}
那么默认情况下在内存里是先排a,再排b
也就是如果能取到a的地址,和b的地址,则相差一个int类型的长度,4字节
[StructLayout(LayoutKind.Sequential)]
struct S1
{
int a;
int b;
}
这样和上一个是一样的.因为默认的内存排列就是Sequential,也就是按成员的先后顺序排列.
2.Explicit,精确布局
需要用FieldOffset()设置每个成员的位置
这样就可以实现类似c的公用体的功能
[StructLayout(LayoutKind.Explicit)]
struct S1
{
[FieldOffset(0)]
int a;
[FieldOffset(0)]
int b;
}
这样a和b在内存中地址相同

StructLayout特性支持三种附加字段:CharSet、Pack、Size。
· CharSet定义在结构中的字符串成员在结构被传给DLL时的排列方式。可以是Unicode、Ansi或Auto。
默认为Auto,在WIN NT/2000/XP中表示字符串按照Unicode字符串进行排列,在WIN 95/98/Me中则表示按照ANSI字符串进行排列。
· Pack定义了结构的封装大小。可以是1、2、4、8、16、32、64、128或特殊值0。特殊值0表示当前操作平台默认的压缩大小。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct LIST_OPEN
{
public int dwServerId;
public int dwListId;
public System.UInt16 wRecordSize;
public System.UInt16 wDummy;
public int dwFileSize;
public int dwTotalRecs;
public NS_PREFETCHLIST sPrefetch;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
public string szSrcMach;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
public string szSrcComp;
}

此例中用到MashalAs特性,它用于描述字段、方法或参数的封送处理格式。用它作为参数前缀并指定目标需要的数据类型。
例如,以下代码将两个参数作为数据类型长指针封送给 Windows API 函数的字符串 (LPStr):
[MarshalAs(UnmanagedType.LPStr)]
String existingfile;
[MarshalAs(UnmanagedType.LPStr)]
String newfile;
注意结构作为参数时候,一般前面要加上ref修饰符,否则会出现错误:对象的引用没有指定对象的实例。
[ DllImport( “kernel32”, EntryPoint=“GetVersionEx” )]
public static extern bool GetVersionEx2( ref OSVersionInfo2 osvi );

结论:
默认(LayoutKind.Sequential)情况下,CLR对struct的Layout的处理方法与C/C++中默认的处理方式相同,即按照结构中占用空间最大的成员进行对齐(Align);
使用LayoutKind.Explicit的情况下,CLR不对结构体进行任何内存对齐(Align),而且我们要小心就是FieldOffset;
使用LayoutKind.Auto的情况下,CLR会对结构体中的字段顺序进行调整,使实例占有尽可能少的内存,并进行4byte的内存对齐(Align)。

最后一个是比较详细的介绍了平台调用的结构体对齐和内存布局

第二:特殊的情况下,C++代码使用#pragma pack(n)改变了边界对齐。这里要使用C#要使用 [StructLayout(LayoutKind.Sequential, Pack = N)] 对齐,否则出错。

网址:关于[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] 的解释 https://www.yuejiaxmz.com/news/view/294845

相关内容

创建表时附带的ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE = utf8
关于html中head的写法.
基于android的健康管理APP
关于释放压力的说说(人生哲学:释放压力,轻松生活)
关于如何帮孩子释放压力
司法解释丨最高人民法院关于适用《中华人民共和国民法典》婚姻家庭编的解释(一)
基于微信小程序的智慧生活助手系统设计与实现(源码+lw+部署+讲解)
居家的解释
决策支持系统的模型解释与可解释性
最高人民法院关于修改《最高人民法院关于审理人身损害赔偿案件适用法律若干问题的解释》的决定

随便看看