首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

从C#程序中调用非受管DLLs,关于属性[StructLayout(LayoutKind.Sequential)],该怎么处理

2012-01-19 
从C#程序中调用非受管DLLs,关于属性[StructLayout(LayoutKind.Sequential)]大家都知道,如果我们为了从C#中

从C#程序中调用非受管DLLs,关于属性[StructLayout(LayoutKind.Sequential)]
大家都知道,如果我们为了从C#   中调用非受管DLLs函数,首先必须要有一个声明,在C#中使用的是DllImport关键字,例如下面的例子:
using   System.Runtime.InteropServices;   //   DllImport所在的名字空间
[StructLayout(LayoutKind.Sequential)]
      public   struct   POINT   {
            public   POINT(int   xx,   int   yy)   {   x=xx;   y=yy;   }
            public   int   x;
            public   int   y;
            public   override   string   ToString()   {
                  String   s   =   String.Format( "({0},{1}) ",   x,   y);
                  return   s;
            }
      }

      [StructLayout(LayoutKind.Sequential)]
      public   struct   SIZE   {
            public   SIZE(int   cxx,   int   cyy)   {   cx=cxx;   cy=cyy;   }
            public   int   cx;
            public   int   cy;
            public   override   string   ToString()   {
                  String   s   =   String.Format( "({0},{1}) ",   cx,   cy);
                  return   s;
            }
      }

      [StructLayout(LayoutKind.Sequential)]
      public   struct   RECT   {
            public   int   left;
            public   int   top;
            public   int   right;
            public   int   bottom;
            public   int   Width()             {   return   right   -   left;   }
            public   int   Height()           {   return   bottom   -   top;   }
            public   POINT   TopLeft()     {   return   new   POINT(left,top);   }
            public   SIZE     Size()           {   return   new   SIZE(Width(),   Height());   }
            public   override   string   ToString()   {
                  String   s   =   String.Format( "{0}x{1} ",   TopLeft(),   Size());
                  return   s;
            }
      }

public   class   Win32   {
    [DllImport( "User32.Dll ")]
    public   static   extern   int   GetWindowRect(int   hwnd,   ref   RECT   rc);


}
上面声明的参数,就可以传递给非受管函数了。
[StructLayout(LayoutKind.Sequential)]这个的意思是使传入的参数是已排序的。
我想问,如果这个属性不写呢,会发生什么?(它的另外2个枚举属性不经常使用)我在使用ILDASM反编译后发现,这个属性写与不写编译结果是一样的。但是我看了好多网上的源代码,发现很多人都是显示的声明的,我很疑惑,我以为它的默认缺省值是[StructLayout(LayoutKind.Sequential)],不知道对吗?请大大出来帮忙解释下,谢谢了!

[解决办法]
举个例子,当你调用的某个API,需要一个结构体作为参数的话,那么就必须给这个结构体设这个Attribute
[解决办法]
默认是没有的,是NET会对这个结构体的内存存放进行优化或者改变
你用ILDASM看到的设置了这个属性和没设置这个属性是一样的结果是巧合
设置这个属性表明这个结构是顺序存放的,这个顺序是指内存顺序,如果你要调用C或者C++的DLL的话,不设置这个顺序可能引起内存访问违背的问题,也可能不会有,完全取决于编译器是否优化了结构体的内存存放,因此很多人显示申明,是为了防止很多不可预知的以外
以上是我的理解,希望对你有点帮助

热点排行