StructLayout特性

StructLayout特性     
     公
共语言运行库利用StructLayoutAttribute控制类或结构的数据字段在托管内存中的物理布局,即类或结构需要按某种方式排列。如果要将类
传递给需要指定布局的非托管代码,则显式控制类布局是重要的。它的构造函数中用
LayoutKind值初始化 StructLayoutAttribute 类的新实例。 LayoutKind.Sequential 用于强制将成
员按其出现的顺序进行顺序布局。
 
 
StructLayout特性允许我们控制Structure语句块的元素在内存中的排列方式,以及当这些元素被传递给外部DLL时,运行库排列这些元素
的方式。Visual  
Basic结构的成员在内存中的顺序是按照它们出现在源代码中的顺序排列的,尽管编译器可以自由的插入填充字节来安排这些成员,以便使得16位数值用子边
界对齐,32位数值用双字边界对齐。    
   
  使用这种排列(未压缩布局)提供的性能最佳。     
        
 
在Visual   Basic  
6的用户自定义结构是未压缩的,而且我们不可以改变这一默认设置。在VB.NET中可以改变这种设置,并且可以通过
System.Runtime.InteropServices.StructLayout   特性精确的控制每一个结构成员的位置。
System.Runtime.InteropServices.StructLayout   允许的值有StructLayout.Auto   StructLayout.Sequential   StructLayout.Explicit.     
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 );

StructLayout特性(转)的更多相关文章

  1. StructLayout特性

    StructLayout特性          公共语言运行库利用 StructLayoutAttribute控制类或结构的数据字段在托管内存中的物理布局,即类或结构需要按某种方式排列.如果要将类传递 ...

  2. [转]StructLayout特性

    转自:http://www.cnblogs.com/JessieDong/archive/2009/07/21/1527553.html StructLayout特性 StructLayout特性   ...

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

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

  4. C# StructLayout(LayoutKind.Sequential)]

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

  5. C#中调用Windows API的要点 .

    介绍 API(Application Programming Interface),我想大家不会陌生,它是我们Windows编程的常客,虽然基于.Net平台的C#有了强大的类库,但是,我们还是不能否认 ...

  6. C#中sizeof的用法实例分析

    这篇文章主要介绍了C#中sizeof的用法,包括了常见的用法及注释事项,需要的朋友可以参考下.   sizeof是C#中非常重要的方法,本文就以实例形式分析C#中sizeof的用法.分享给大家供大家参 ...

  7. C# 与C++的数据转换

    一.类型转化 下面重点罗列下常用的类型转化. C++类型 C#类型 备注说明 Int Int16.Int32 没有悬念,直接转化 Uint UInt16.Uint32.int 在程序中,不太清楚是,就 ...

  8. 【转帖】C# DllImport 系统调用使用详解 托管代码的介绍 EntryPoint的使用

    1      DLLImport的使用 using System; using System.Runtime.InteropServices; //命名空间 class Example { //用Dl ...

  9. IntPtr问题

    public aaa(IntPtr myPtr,int left, int top, int width, short height) 这里myPtr应该是对应到一块内存,你需要查看aaa函数是如何把 ...

随机推荐

  1. MS Chart-按照数据库的最大最小时间设置X轴label.

    核心代码: Chart1.ChartAreas[0].AxisX.Interval = (Front_Max - Front_Min).Days / 2; Chart1.ChartAreas[0].A ...

  2. APM飞控修改数传模块方法

    APM飞控修改数传模块方法 硬件 ARDUCOPTER第二代 数传模块(USB接口) 数传模块(telem接口) usb-ttl模块 修改方法 注意:APM固件版本和数传模块估计版本是分开的,但有一定 ...

  3. 16位CPU多周期设计

    16位CPU多周期设计 这个工程完成了16位CPU的多周期设计,模块化设计,有包含必要的分析说明. 多周期CPU结构图 多周期CPU设计真值表 对应某一指令的情况,但仅当对应周期时才为对应的输出,不是 ...

  4. 用Sqlplus手动创建Oracle11g数据库

    用Sqlplus手动创建Oracle数据库 刚开始学习Oracle数据库,菜鸟一个,使用sqlplus创建数据库遇到了很多问题,通过不断地百度,终于创建成功了.所以顺便把整个过程中犯的一些最低级的错误 ...

  5. 如何把bootstrap用webpack打包

    今天下载了一个anguarl2写后台,一直没有找到是如何使用bootstrap样式的,然后就全文做了搜索,发现有一段代码 import 'bootstrap-loader'; 这段代码很可疑,所以就查 ...

  6. C++中数组求偏移量计算公式

    已知数组:type A[10][5]A[0][0] --A[8][4]面试常考:数组定义A[0....x][0...y]已知A[m][n] --求A[k][l]的地址:    &A[m][n] ...

  7. UITableView 应用及其总结

    Plain: Grouped: Cell的结构图: UITableViewCellStyleDefault:预设使用这种,若左侧ImageView没图的话,只有一行字(textLable.text). ...

  8. 任务:写一个tomcat自启动脚本

    写一篇<gitlab无法启动了应该怎么办>

  9. 如何不通过系统升级来安装window10正式版?(特别针对Xp用户)

    今天是个特殊的日子7/29,相信大家都等了很久了吧,win10正式版终于上线,一些不懂电脑的人只会通过360和腾讯管家等来升级到win10(XP用户除外),而对于大多数像我这样对系统比较热衷的人,我相 ...

  10. storm集成kafka

    kafkautil: import java.util.Properties; import kafka.javaapi.producer.Producer; import kafka.produce ...