关于[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)] 的解释的更多相关文章

  1. C# StructLayout(LayoutKind.Sequential)]

      结构体是由若干成员组成的.布局有两种1.Sequential,顺序布局,比如struct S1{ int a; int b;}那么默认情况下在内存里是先排a,再排b也就是如果能取到a的地址,和b的 ...

  2. [StructLayout(LayoutKind.Sequential) ] 是什么意思

    首先介绍一下 结构体和类的区别 :类是按引用传递 结构体是按值传递进入正题:结构体是由若干成员组成的.布局有两种1.Sequential,顺序布局,比如struct S1{int a;int b;}那 ...

  3. C#:[StructLayout(LayoutKind.Sequential)]

    参考网址: https://blog.csdn.net/hongkonglife/article/details/23422857 结构体是由若干成员组成的.布局有两种1.Sequential,顺序布 ...

  4. String(byte[] bytes, Charset charset) 和 getBytes() 使用

    转自:https://techbirds.iteye.com/blog/1855960 @Test public void testBytes(){ //字节数 //中文:ISO:1 GBK:2 UT ...

  5. 类结构体 与 byte[] 转换类

    public static class StructConvert { public static object BytesToStruct(byte[] bytes, Type strcutType ...

  6. C# TreeView使用技巧

    节点勾选设置 TreeView树中节点勾选要求: 1.不选中一个节点,则其所有的子节点都不被选中. 2.选中一个节点,则其所有的子节点都被选中. 3.当一个节点的所有子节点都没有被选中时,该节点也没有 ...

  7. 给C#的treeview控件的部分节点添加checkbox

    一.先初始化treeview this.treeView1.CheckBoxes = true; this.treeView1.ShowLines = false; this.treeView1.Dr ...

  8. C# treeview控件部分节点添加checkbox

    一.先初始化treeview this.treeView1.CheckBoxes = true; this.treeView1.ShowLines = false; this.treeView1.Dr ...

  9. C#关于xml文件和TreeView之间的转换解析

    主窗体: using System; using System.Collections; using System.Collections.Generic; using System.Componen ...

随机推荐

  1. java中List集合

    List集合是一个元素有序可以重复的集合,集合中每个元素都有其对应的顺序索引.List集合允许使用重复集合,前面博客写到Set不允许有重复集合.List集合可以通过索引来访问指定位置的集合元素. Li ...

  2. tomcat 启动项目超时问题

    在开发工具中打开tomcat(F3),Timesouts下设置增加start秒数,然后保存重启项目.

  3. STAF Trust Level 4 required for FS copy request

    C#中使用STAF从本机传输文件到远程的电脑,出现如下错误: 解决方法: 修改service.ini文件,添加信任IP段,并将trust level 设置为5,修改后文件内容如下 trace enab ...

  4. 什么是ARP协议?

    ARP协议,全称“Address Resolution Protocol”,中文名是地址解析协议, 使用ARP协议可实现通过IP地址获得对应主机的物理地址(MAC地址). 在TCP/IP的网络环境下, ...

  5. 使用fastjson 进行jsonObject转实体类对象

    使用fastjson 进行jsonObject转实体类对象   1 <dependency> 2 <groupId>com.alibaba</groupId> 3 ...

  6. Centos7 minimal 安装npm

    最小版本缺少很多源,需要手动去添加源 如何去判断yum中 有没有 npm 的源呢 yum list | grep npm 如果是这样的,就代表需要自己去添加 curl -sL -o /etc/yum. ...

  7. .net web api 返回的是xml

    var result = new HttpResponseMessage { Content = new StringContent(JsonConvert.SerializeObject(dto2) ...

  8. C函数指针数组的定义和使用

    1.使用函数指针数组来实现计算器 2.通过函数指针变量来调用对应的函数 #include <stdio.h> int add(int a,int b){ return a+b; } int ...

  9. pytorch imagenet测试代码

    image_test.py import argparse import numpy as np import sys import os import csv from imagenet_test_ ...

  10. Linux运维:安装CentOS7图解

    Ago linux运维群: 93324526 笔者QQ:578843228 此篇博文针对最小化安装,和只有图解.有不懂地方,欢迎加群询问. 此篇以CentOS7.2为例