关于[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] 的解释
关于[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] 的解释
[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)] 对齐,否则出错。
http://www.cnblogs.com/namek/archive/2010/08/26/1808773.html
关于[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] 的解释的更多相关文章
- C# StructLayout(LayoutKind.Sequential)]
结构体是由若干成员组成的.布局有两种1.Sequential,顺序布局,比如struct S1{ int a; int b;}那么默认情况下在内存里是先排a,再排b也就是如果能取到a的地址,和b的 ...
- [StructLayout(LayoutKind.Sequential) ] 是什么意思
首先介绍一下 结构体和类的区别 :类是按引用传递 结构体是按值传递进入正题:结构体是由若干成员组成的.布局有两种1.Sequential,顺序布局,比如struct S1{int a;int b;}那 ...
- C#:[StructLayout(LayoutKind.Sequential)]
参考网址: https://blog.csdn.net/hongkonglife/article/details/23422857 结构体是由若干成员组成的.布局有两种1.Sequential,顺序布 ...
- String(byte[] bytes, Charset charset) 和 getBytes() 使用
转自:https://techbirds.iteye.com/blog/1855960 @Test public void testBytes(){ //字节数 //中文:ISO:1 GBK:2 UT ...
- 类结构体 与 byte[] 转换类
public static class StructConvert { public static object BytesToStruct(byte[] bytes, Type strcutType ...
- C# TreeView使用技巧
节点勾选设置 TreeView树中节点勾选要求: 1.不选中一个节点,则其所有的子节点都不被选中. 2.选中一个节点,则其所有的子节点都被选中. 3.当一个节点的所有子节点都没有被选中时,该节点也没有 ...
- 给C#的treeview控件的部分节点添加checkbox
一.先初始化treeview this.treeView1.CheckBoxes = true; this.treeView1.ShowLines = false; this.treeView1.Dr ...
- C# treeview控件部分节点添加checkbox
一.先初始化treeview this.treeView1.CheckBoxes = true; this.treeView1.ShowLines = false; this.treeView1.Dr ...
- C#关于xml文件和TreeView之间的转换解析
主窗体: using System; using System.Collections; using System.Collections.Generic; using System.Componen ...
随机推荐
- 个性化排序算法实践(二)——FFM算法
场感知分解机(Field-aware Factorization Machine ,简称FFM)在FM的基础上进一步改进,在模型中引入类别的概念,即field.将同一个field的特征单独进行one- ...
- java中List集合
List集合是一个元素有序可以重复的集合,集合中每个元素都有其对应的顺序索引.List集合允许使用重复集合,前面博客写到Set不允许有重复集合.List集合可以通过索引来访问指定位置的集合元素. Li ...
- js与jquery中html() text() val()中的区别
首先html() text() val() 是jquery方法. 1.html()取得内容可以包含标签. 2.text()取得内容为元素文本内容. 3.val()只有value属性的元素才能使用该方法 ...
- windows nginx 目录配置
http { server { listen 80; server_name www.test.com; location / { root E:/data/www; index index.html ...
- Hibernate框架的查询方式
技术分析之Hibernate框架的查询方式 1. 唯一标识OID的检索方式 * session.get(对象.class,OID) 2. 对象的导航的方式 ...
- Linux下dstat的安装(适用任何版本)
dstat下载地址:https://pan.baidu.com/s/1jHTEoWe 1.上传后,解压: 2.进入解压后的目录:cd dstat-0.7.3/ 3.make 4.make instal ...
- Dominating Patterns (AC 自动鸡模版题, 出现次数最多的子串)
传送门 题意: 给你n个模式串, 再给你一个 文本串,问模式串在文本串中出现次数最多是多少. 出现次数最多的模式串有哪些. 解: 模版题. #include <bits/stdc++.h> ...
- leetcode解题报告(27):Reverse Linked List
描述 Reverse a singly linked list. 分析 一开始写的时候总感觉没抓到要点,然后想起上数据结构课的教材上有这道题,翻开书一看完就回忆起来了,感觉解法挺巧妙的,不比讨论区的答 ...
- nyar4psg: Cannot find a class or type named "MultiMarker"
Cannot find a class or type named "MultiMarker" 是一种常见错误,产生的原因是Library里面有1个以上的ar库. 以我的电脑为例, ...
- lixuxmint系统定制与配置(1)-系统初始配置
小书匠Linux 经常安装新的系统,每次安装完都得去搜索一边如何将系统部署为之前的环境,不仅耗费时间,还不一定能弄回之前的环境,现在把从裸机->到工作环境的系统定制及配置过程记录下来,期间的配置 ...