在引用dll中的DllImport 、StructLayout 、 FieldOffset 、Marshal、和 C++(windows API)对应C#的数据类型

在我们引用DLL的时候经常会用到一些类比如 DllImport 、StructLayout 、 FieldOffset 、Marshal,那么这些类有什么作用呢?还有一个就是C++的数据类型与C#数据类型如何对应呢?下面来一一介绍一下。

一 、DllImport导入dll

用于导入dll,具体介绍请移步到另外一篇文章:C#中DllImport用法和路径问题

using System;
using System.Runtime.InteropServices;

class Example
{
    // 使用DllImport导入 Win32 MessageBox 的功能.
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
    
    static void Main()
    {
        // 平台调用MessageBox
        MessageBox(new IntPtr(0), "Hello World!", "Hello Dialog", 0);
    }
}

二、StructLayout 控制字段的物理布局

StructLayout 允许控制内存中类或结构的数据字段的物理布局。
应用 StructLayoutAttribute 属性以确保成员在内存中按出现的顺序进行排列

示例代码:

 [StructLayout(LayoutKind.Explicit, Size=16, CharSet=CharSet.Ansi)]
   public class MySystemTime
   {
      [FieldOffset(0)]public ushort wYear;
      [FieldOffset(2)]public ushort wMonth;
      [FieldOffset(4)]public ushort wDayOfWeek;
      [FieldOffset(6)]public ushort wDay;
      [FieldOffset(8)]public ushort wHour;
      [FieldOffset(10)]public ushort wMinute;
      [FieldOffset(12)]public ushort wSecond;
      [FieldOffset(14)]public ushort wMilliseconds;
   }

StructLayoutAttribute 的字段有 CharSet , Pack 和 Size 还有一个枚举LayoutKind

    ① CharSet: 指示在默认情况下是否应将类中的字符串数据字段作为 LPWSTR 或 LPSTR 进行封送处理
    如果 CharSet 字段设置为 CharSet.Unicode 或,则在 CharSet.Auto 将所有字符串参数 LPWSTR 传递到非托管实现之前,将 () 转换为 Unicode 字符。 如果字段设置为 CharSet.Ansi ,则会将字符串转换为 ANSI 字符串 (LPSTR) 。

        a:  None   //与Ansi具有相同的行为
        b: Ansi      // 以多字节字符串的形式封送字符串
        c: Unicode   // Unicode 2 字节字符形式封送字符串
        d: Auto      //针对目标操作系统适当地自动封送字符串
        
        
        

②  Pack    设置类或结构的数据字段在内存中的对齐方式
Pack字段控制类型字段在内存中的对齐方式。 它会影响 LayoutKind.Sequential 。 默认情况下,此值为0,指示当前平台的默认封装大小的值。 Pack 必须为0、1、2、4、8、16、32、64或128:

使用以下规则对齐类型实例的字段:
•	该类型的对齐方式是它的最大元素的大小 (1、2、4、8等)、字节) 或指定的封装大小(以较小者为准)。
•	每个字段都必须与其自身大小的字段 (1、2、4、8等、字节) 或该类型的对齐方式相匹配,取两者中较小者。 
    因为该类型的默认对齐方式是其最大元素的大小,该大小大于或等于所有其他字段长度,这通常意味着字段按其大小对齐。 
    例如,即使类型中的最大字段为64位 (8 字节) 整数或 Pack 字段设置为8, 
    Byte 字段将在1字节边界上对齐, Int16 字段在2字节边界对齐, Int32 字段在4字节边界上对齐。
•	在字段之间添加填充以满足对齐要求。

③ Size  类或结构的绝对大小(Int32)
  此字段必须等于或大于类或结构的成员的总大小(以字节为单位)。
  此字段主要适用于想要扩展结构占用的内存以实现直接的非托管访问的编译器编写器.


④  public enum LayoutKind 枚举
Auto	    3	      运行库自动为非托管内存中的对象的成员选择适当的布局。 使用此枚举成员定义的对象不能在托管代码的外部公开。 尝试这样做将引发异常。
Explicit	2	       在未管理内存中的每一个对象成员的精确位置是被显式控制的,服从于 Pack 字段的设置。 
                        每个成员必须使用 FieldOffsetAttribute 指示该字段在类型中的位置。

Sequential	0	      对象的成员按照它们在被导出到非托管内存时出现的顺序依次布局。 这些成员根据在 Pack 中指定的封装进行布局,并且可以是不连续的。

官网MSDN关于StructLayoutAttribute 的介绍

三、FieldOffset 字段的偏移位置

指示类或结构的非托管表示形式中字段的物理位置.

注:当StructLayout 中LayoutKind的值是 LayoutKind.Explicit时,可以将FieldOffset 应用于类或结构,以指定该类或结构的非托管表示形式中每个非static或常量成员的偏移量

官网MSDN关于FieldOffsetAttribute的介绍

四、 Marshal 分配或复制非托管内存 将托管类型转换为非托管类型

Marshal 提供了一个方法集合,这些方法用于分配非托管内存、复制非托管内存块、将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法。

示例代码:

using System;
using System.Text;
using System.Runtime.InteropServices;

public struct Point
{
    public Int32 x, y;
}

public sealed class App
{
    static void Main()
    {
        // 演示一下Marshal类的静态字段.
        Console.WriteLine("SystemDefaultCharSize={0}, SystemMaxDBCSCharSize={1}",
            Marshal.SystemDefaultCharSize, Marshal.SystemMaxDBCSCharSize);

        // Marshal的SizeOf方法.
        Console.WriteLine("Number of bytes needed by a Point object: {0}",
            Marshal.SizeOf(typeof(Point)));
        Point p = new Point();
        Console.WriteLine("Number of bytes needed by a Point object: {0}",
            Marshal.SizeOf(p));

        // 如何调用Marshal类中的 GlobalAlloc 和 GlobalFree 方法
        IntPtr hglobal = Marshal.AllocHGlobal(100);
        Marshal.FreeHGlobal(hglobal);

        // 如何使用Marshal类来获取Win32错误
        // 当win32方法失败时
        Boolean f = CloseHandle(new IntPtr(-1));
        if (!f)
        {
            Console.WriteLine("CloseHandle call failed with an error code of: {0}",
                Marshal.GetLastWin32Error());
        }
    }

    //这是一个平台调用原型。当SetLastError为true时,
   // Marshal类的GetLastWin32Error方法才能正常工作。
    [DllImport("Kernel32", ExactSpelling = true, SetLastError = true)]
    static extern Boolean CloseHandle(IntPtr h);
}

// 输出.
//
// SystemDefaultCharSize=2, SystemMaxDBCSCharSize=1
// Number of bytes needed by a Point object: 8
// Number of bytes needed by a Point object: 8
// CloseHandle call failed with an error code of: 6

字段 SystemDefaultCharSizeSystemMaxDBCSCharSize

1、SystemDefaultCharSize : 
      系统上的默认字符大小;Unicode 系统上默认值为 2,ANSI 系统上默认值为 1。 此字段为只读 
      
2、SystemMaxDBCSCharSize:
       表示用于当前操作系统的双字节字符集 (DBCS) 的最大大小(以字节为单位)。 此字段为只读

方法

SizeOf()         :返回类的非托管大小(以字节为单位)。  
AllocHGlobal(Int32)   通过使用指定的字节数,从进程的非托管内存中分配内存。
FreeHGlobal(IntPtr)    释放以前从进程的非托管内存中分配的内存。
GetLastWin32Error()      返回由上一个非托管函数返回的错误代码,该函数是使用设置了 SetLastError 标志的平台调用来的。
AddRef(IntPtr)	
递增指定接口上的引用计数。

AllocCoTaskMem(Int32)	
从 COM 任务内存分配器分配指定大小的内存块。

AllocHGlobal(Int32)	
通过使用指定的字节数,从进程的非托管内存中分配内存。

AllocHGlobal(IntPtr)	
通过使用指向指定字节数的指针,从进程的非托管内存中分配内存。

AreComObjectsAvailableForCleanup()	
指示是否可以清除任何上下文中的运行时可调用包装器 (RCW)BindToMoniker(String)	
获取由指定的名字对象标识的接口指针。

ChangeWrapperHandleStrength(Object, Boolean)	
更改对象的 COM 可调用包装器 (CCW) 句柄的强度。

CleanupUnusedObjectsInCurrentContext()	
通知运行时清理当前上下文中分配的所有运行时可调用包装器 (RCW)Copy(Byte[], Int32, IntPtr, Int32)	
将数据从一维托管 8 位无符号整数数组复制到非托管内存指针。

Copy(Char[], Int32, IntPtr, Int32)	
将数据从一维托管字符数组复制到非托管内存指针。

Copy(Double[], Int32, IntPtr, Int32)	
将数据从一维托管双精度浮点数数组复制到非托管内存指针。

Copy(Int16[], Int32, IntPtr, Int32)	
将数据从一维托管 16 位带符号整数数组复制到非托管内存指针。

Copy(Int32[], Int32, IntPtr, Int32)	
将数据从一维托管 32 位带符号整数数组复制到非托管内存指针。

Copy(Int64[], Int32, IntPtr, Int32)	
将数据从一维托管 64 位带符号整数数组复制到非托管内存指针。

Copy(IntPtr, Byte[], Int32, Int32)	
将数据从非托管内存指针复制到托管 8 位无符号整数数组。

Copy(IntPtr, Char[], Int32, Int32)	
将数据从非托管内存指针复制到托管字符数组。

Copy(IntPtr, Double[], Int32, Int32)	
将数据从非托管内存指针复制到托管双精度浮点数数组。

Copy(IntPtr, Int16[], Int32, Int32)	
将数据从非托管内存指针复制到托管 16 位带符号整数数组。

Copy(IntPtr, Int32[], Int32, Int32)	
将数据从非托管内存指针复制到托管 32 位带符号整数数组。

Copy(IntPtr, Int64[], Int32, Int32)	
将数据从非托管内存指针复制到托管 64 位带符号整数数组。

Copy(IntPtr, IntPtr[], Int32, Int32)	
将数据从非托管的内存指针复制到托管的 IntPtr 数组。

Copy(IntPtr, Single[], Int32, Int32)	
将数据从非托管内存指针复制到托管单精度浮点数数组。

Copy(IntPtr[], Int32, IntPtr, Int32)	
将数据从一维托管的 IntPtr 数组复制到非托管内存指针。

Copy(Single[], Int32, IntPtr, Int32)	
将数据从一维托管单精度浮点数数组复制到非托管内存指针。

CreateAggregatedObject(IntPtr, Object)	
聚合托管对象和指定的 COM 对象。

CreateAggregatedObject<T>(IntPtr, T)	
[.NET Framework 4.5.1 和更高版本中受支持]

聚合指定类型的托管对象和指定的 COM 对象。

CreateWrapperOfType(Object, Type)	
在指定类型的对象中包装指定的 COM 对象。

CreateWrapperOfType<T,TWrapper>(T)	
[.NET Framework 4.5.1 和更高版本中受支持]

在指定类型的对象中包装指定的 COM 对象。

DestroyStructure(IntPtr, Type)	
释放指定的非托管内存块所指向的所有子结构。

DestroyStructure<T>(IntPtr)	
[.NET Framework 4.5.1 和更高版本中受支持]

释放指定的非托管内存块所指向的所有指定类型的子结构。

FinalReleaseComObject(Object)	
通过将运行时可调用包装器 (RCW) 的引用计数设置为 0,释放对它的所有引用。

FreeBSTR(IntPtr)	
使用 COM SysFreeString 函数释放 BSTR。

FreeCoTaskMem(IntPtr)	
释放由非托管 COM 任务内存分配器分配的内存块。

FreeHGlobal(IntPtr)	
释放以前从进程的非托管内存中分配的内存。

GenerateGuidForType(Type)	
返回指定类型的全局唯一标识符 (GUID),或使用类型库导出程序 (Tlbexp.exe) 所用的算法生成 GUID。

GenerateProgIdForType(Type)	
返回指定类型的编程标识符 (ProgID)GetComInterfaceForObject(Object, Type)	
返回一个指向 IUnknown 接口的指针,该指针表示指定对象上的指定接口。 默认情况下,启用自定义查询接口访问。

GetComInterfaceForObject(Object, Type, CustomQueryInterfaceMode)	
返回一个指向 IUnknown 接口的指针,该指针表示指定对象上的指定接口。 自定义查询接口访问由指定的自定义模式控制。

GetComInterfaceForObject<T,TInterface>(T)	
[.NET Framework 4.5.1 和更高版本中受支持]

返回一个指向 IUnknown 接口的指针,该指针表示指定类型的对象上的指定接口。 默认情况下,启用自定义查询接口访问。

GetComObjectData(Object, Object)	
从指定的 COM 对象检索指定键所引用的数据。

GetDelegateForFunctionPointer(IntPtr, Type)	
将非托管函数指针转换为委托。

GetDelegateForFunctionPointer<TDelegate>(IntPtr)	
[.NET Framework 4.5.1 和更高版本中受支持]

将非托管函数指针转换为指定类型的委托。

GetEndComSlot(Type)	
检索向 COM 公开时某个类型的虚拟功能表(v 表或 VTBL)中的最后一个槽。

GetExceptionCode()	
已过时。
检索标识所发生异常的类型的代码。

GetExceptionForHR(Int32)	
将指定的 HRESULT 错误代码转换为对应的 Exception 对象。

GetExceptionForHR(Int32, IntPtr)	
将指定的 HRESULT 错误代码转换为对应的 Exception 对象,其中包括通过此异常对象的 IErrorInfo 接口传递的其他错误信息。

GetExceptionPointers()	
检索与计算机无关的异常描述,以及有关异常发生时线程的状态信息。

GetFunctionPointerForDelegate(Delegate)	
将委托转换为可从非托管代码调用的函数指针。

GetFunctionPointerForDelegate<TDelegate>(TDelegate)	
[.NET Framework 4.5.1 和更高版本中受支持]

将指定类型的委托转换为可从非托管代码调用的函数指针。

GetHINSTANCE(Module)	
返回指定模块的实例句柄 (HINSTANCE)GetHRForException(Exception)	
将指定异常转换为 HRESULT。

GetHRForLastWin32Error()	
返回 HRESULT,它对应于使用 Marshal 执行的 Win32 代码引起的最后一个错误。

GetIDispatchForObject(Object)	
从托管对象返回一个 IDispatch 接口。

GetIUnknownForObject(Object)	
从托管对象返回 IUnknown 接口。

GetLastPInvokeError()	
获取当前线程上最后一个平台调用错误。

GetLastSystemError()	
获取当前线程上的最后一个系统错误。

GetLastWin32Error()	
返回由上一个非托管函数返回的错误代码,该函数是使用设置了 SetLastError 标志的平台调用来的。

GetNativeVariantForObject(Object, IntPtr)	
将对象转换为 COM VARIANT。

GetNativeVariantForObject<T>(T, IntPtr)	
[.NET Framework 4.5.1 和更高版本中受支持]

将指定类型的对象转换为 COM VARIANT。

GetObjectForIUnknown(IntPtr)	
返回一个类型实例,该实例通过指向 COM 对象的 IUnknown 接口的指针表示该对象。

GetObjectForNativeVariant(IntPtr)	
将 COM VARIANT 转换为对象。

GetObjectForNativeVariant<T>(IntPtr)	
[.NET Framework 4.5.1 和更高版本中受支持]

将 COM VARIANT 转换为指定类型的对象。

GetObjectsForNativeVariants(IntPtr, Int32)	
将 COM VARIANT 数组转换为对象数组。

GetObjectsForNativeVariants<T>(IntPtr, Int32)	
[.NET Framework 4.5.1 和更高版本中受支持]

将 COM VARIANT 数组转换为指定类型的数组。

GetStartComSlot(Type)	
获取虚拟功能表(v 表或 VTBL)中包含用户定义的方法的第一个槽。

GetTypedObjectForIUnknown(IntPtr, Type)	
返回表示 COM 对象的指定类型的托管对象。

GetTypeFromCLSID(Guid)	
返回与指定的类标识符 (CLSID) 关联的类型。

GetTypeInfoName(ITypeInfo)	
检索由 ITypeInfo 对象表示的类型的名称。

GetUniqueObjectForIUnknown(IntPtr)	
为给定的 IUnknown 接口创建唯一的运行时可调用包装器 (RCW) 对象。

InitHandle(SafeHandle, IntPtr)	
初始化新创建 SafeHandle 的值的基础句柄。

IsComObject(Object)	
指示指定对象是否表示 COM 对象。

IsTypeVisibleFromCom(Type)	
指示类型对 COM 客户端是否可见。

OffsetOf(Type, String)	
返回托管类的非托管形式的字段偏移量。

OffsetOf<T>(String)	
[.NET Framework 4.5.1 和更高版本中受支持]

返回指定托管类的非托管形式的字段偏移量。

Prelink(MethodInfo)	
在不调用方法的情况下执行一次性方法设置任务。

PrelinkAll(Type)	
对类上的所有方法执行预链接检查。

PtrToStringAnsi(IntPtr)	
将非托管 ANSI 或 UTF-8 字符串中第一个空字符之前的所有字符复制到托管 String,并将每个字符扩展为 UTF-16 字符。

PtrToStringAnsi(IntPtr, Int32)	
分配托管 String,然后从非托管 ANSI 或 UTF-8 字符串向其复制指定数目的字符,并将每个字符扩展为 UTF-16 字符。

PtrToStringAuto(IntPtr)	
分配托管 String,并从非托管内存中存储的字符串向其复制第一个空字符之前的所有字符。

PtrToStringAuto(IntPtr, Int32)	
分配托管 String,并从存储在非托管内存中的字符串向其复制指定数目的字符。

PtrToStringBSTR(IntPtr)	
分配已托管的 String,并向其中复制非托管内存中存储的 二进制字符串 (BSTR)PtrToStringUni(IntPtr)	
分配托管 String,并从非托管 Unicode 字符串向其复制第一个空字符之前的所有字符。

PtrToStringUni(IntPtr, Int32)	
分配托管 String,并从非托的 Unicode 字符串向其复制指定数目的字符。

PtrToStringUTF8(IntPtr)	
分配托管的 String,并从非托管的 UTF-8 字符串向其复制第一个空字符之前的所有字符。

PtrToStringUTF8(IntPtr, Int32)	
分配托管的 String,并从非托管的 UTF8 字符串向其复制指定数目的字符。

PtrToStructure(IntPtr, Object)	
将数据从非托管内存块封送到托管对象。

PtrToStructure(IntPtr, Type)	
将数据从非托管内存块封送到新分配的指定类型的托管对象。

PtrToStructure<T>(IntPtr)	
[.NET Framework 4.5.1 和更高版本中受支持]

将数据从非托管内存块封送到泛型类型参数指定的类型的新分配托管对象。

PtrToStructure<T>(IntPtr, T)	
[.NET Framework 4.5.1 和更高版本中受支持]

将数据从非托管内存块封送到指定类型的托管内存对象。

QueryInterface(IntPtr, Guid, IntPtr)	
从 COM 对象请求指向指定接口的指针。

ReadByte(IntPtr)	
从非托管内存读取单个字节。

ReadByte(IntPtr, Int32)	
从非托管内存按给定的偏移量(或索引)读取单个字节。

ReadByte(Object, Int32)	
已过时。
从非托管内存按给定的偏移量(或索引)读取单个字节。

ReadInt16(IntPtr)	
从非托管内存中读取一个 16 位带符号整数。

ReadInt16(IntPtr, Int32)	
从非托管内存按给定的偏移量读取一个 16 位带符号整数。

ReadInt16(Object, Int32)	
已过时。
从非托管内存按给定的偏移量读取一个 16 位带符号整数。

ReadInt32(IntPtr)	
从非托管内存中读取一个 32 位带符号整数。

ReadInt32(IntPtr, Int32)	
从非托管内存按给定的偏移量读取一个 32 位带符号整数。

ReadInt32(Object, Int32)	
已过时。
从非托管内存按给定的偏移量读取一个 32 位带符号整数。

ReadInt64(IntPtr)	
从非托管内存中读取一个 64 位带符号整数。

ReadInt64(IntPtr, Int32)	
从非托管内存按给定的偏移量读取一个 64 位带符号整数。

ReadInt64(Object, Int32)	
已过时。
从非托管内存按给定的偏移量读取一个 64 位带符号整数。

ReadIntPtr(IntPtr)	
从非托管内存读取处理器本机大小的整数。

ReadIntPtr(IntPtr, Int32)	
从非托管内存按给定的偏移量读取处理器本机大小的整数。

ReadIntPtr(Object, Int32)	
已过时。
从非托管内存读取处理器本机大小的整数。

ReAllocCoTaskMem(IntPtr, Int32)	
调整之前用 AllocCoTaskMem(Int32) 分配的内存块的大小。

ReAllocHGlobal(IntPtr, IntPtr)	
调整之前用 AllocHGlobal(IntPtr) 分配的内存块的大小。

Release(IntPtr)	
递减指定接口上的引用计数。

ReleaseComObject(Object)	
递减与指定的 COM 对象关联的运行时可调用包装器 (RCW) 的引用计数。

SecureStringToBSTR(SecureString)	
分配非托管二进制字符串 (BSTR)并将托管 SecureString 对象的内容复制到其中。

SecureStringToCoTaskMemAnsi(SecureString)	
将托管 SecureString 对象的内容复制到从非托管 COM 任务分配器分配的内存块。

SecureStringToCoTaskMemUnicode(SecureString)	
将托管 SecureString 对象的内容复制到从非托管 COM 任务分配器分配的内存块。

SecureStringToGlobalAllocAnsi(SecureString)	
将托管 SecureString 的内容复制到非托管内存,并在复制时转换为 ANSI 格式。

SecureStringToGlobalAllocUnicode(SecureString)	
将托管 SecureString 对象的内容复制到非托管内存中。

SetComObjectData(Object, Object, Object)	
设置由指定 COM 对象中的指定键引用的数据。

SetLastPInvokeError(Int32)	
设置当前线程上的最后一个平台调用错误。

SetLastSystemError(Int32)	
设置当前线程上的最后一个系统错误。

SizeOf(Object)	
返回对象的非托管大小(以字节为单位)。

SizeOf(Type)	
返回非托管类型的大小(以字节为单位)。

SizeOf<T>()	
[.NET Framework 4.5.1 和更高版本中受支持]

返回非托管类型的大小(以字节为单位)。

SizeOf<T>(T)	
[.NET Framework 4.5.1 和更高版本中受支持]

返回指定类型的对象的非托管大小(以字节为单位)。

StringToBSTR(String)	
分配 BSTR 并向其复制托管 String 的内容。

StringToCoTaskMemAnsi(String)	
将托管 String 的内容复制到从非托管 COM 任务分配器分配的内存块。

StringToCoTaskMemAuto(String)	
将托管 String 的内容复制到从非托管 COM 任务分配器分配的内存块。

StringToCoTaskMemUni(String)	
将托管 String 的内容复制到从非托管 COM 任务分配器分配的内存块。

StringToCoTaskMemUTF8(String)	
将托管 String 的内容复制到从非托管 COM 任务分配器分配的内存块。

StringToHGlobalAnsi(String)	
将托管 String 的内容复制到非托管内存,并在复制时转换为 ANSI 格式。

StringToHGlobalAuto(String)	
将托管 String 的内容复制到非托管内存,并在需要时转换为 ANSI 格式。

StringToHGlobalUni(String)	
将托管 String 的内容复制到非托管内存。

StructureToPtr(Object, IntPtr, Boolean)	
将数据从托管对象封送到非托管内存块。

StructureToPtr<T>(T, IntPtr, Boolean)	
[.NET Framework 4.5.1 和更高版本中受支持]

将数据从指定类型的托管对象封送到非托管内存块。

ThrowExceptionForHR(Int32)	
用特定的失败 HRESULT 值引发异常。

ThrowExceptionForHR(Int32, IntPtr)	
基于指定的 IErrorInfo 接口,用特定的失败 HRESULT 引发异常。

UnsafeAddrOfPinnedArrayElement(Array, Int32)	
获取指定数组中指定索引处的元素的地址。

UnsafeAddrOfPinnedArrayElement<T>(T[], Int32)	
[.NET Framework 4.5.1 和更高版本中受支持]

获取指定类型的数组中指定索引处的元素地址。

WriteByte(IntPtr, Byte)	
将单个字节值写入到非托管内存。

WriteByte(IntPtr, Int32, Byte)	
按指定偏移量将单字节值写入非托管内存。

WriteByte(Object, Int32, Byte)	
已过时。
按指定偏移量将单字节值写入非托管内存。

WriteInt16(IntPtr, Char)	
将一个字符作为 16 位整数值写入非托管内存。

WriteInt16(IntPtr, Int16)16 位整数值写入非托管内存。

WriteInt16(IntPtr, Int32, Char)	
按指定偏移量将 16 位带符号整数值写入非托管内存。

WriteInt16(IntPtr, Int32, Int16)	
按指定偏移量将 16 位带符号整数值写入非托管内存。

WriteInt16(Object, Int32, Char)	
已过时。
按指定偏移量将 16 位带符号整数值写入非托管内存。

WriteInt16(Object, Int32, Int16)	
已过时。
按指定偏移量将 16 位带符号整数值写入非托管内存。

WriteInt32(IntPtr, Int32)32 位带符号整数值写入非托管内存。

WriteInt32(IntPtr, Int32, Int32)	
按指定偏移量将 32 位带符号整数值写入非托管内存。

WriteInt32(Object, Int32, Int32)	
已过时。
按指定偏移量将 32 位带符号整数值写入非托管内存。

WriteInt64(IntPtr, Int32, Int64)	
按指定偏移量将 64 位带符号整数值写入非托管内存。

WriteInt64(IntPtr, Int64)64 位带符号整数值写入非托管内存。

WriteInt64(Object, Int32, Int64)	
已过时。
按指定偏移量将 64 位带符号整数值写入非托管内存。

WriteIntPtr(IntPtr, Int32, IntPtr)	
按指定的偏移量将一个处理器本机大小的整数值写入非托管内存。

WriteIntPtr(IntPtr, IntPtr)	
将一个处理器本机大小的整数值写入非托管内存。

WriteIntPtr(Object, Int32, IntPtr)	
已过时。
将一个处理器本机大小的整数值写入非托管内存。

ZeroFreeBSTR(IntPtr)	
释放 BSTR 指针,该指针是使用 SecureStringToBSTR(SecureString) 方法分配的。

ZeroFreeCoTaskMemAnsi(IntPtr)	
释放非托管字符串指针,该指针是使用 SecureStringToCoTaskMemAnsi(SecureString) 方法分配的。

ZeroFreeCoTaskMemUnicode(IntPtr)	
释放非托管字符串指针,该指针是使用 SecureStringToCoTaskMemUnicode(SecureString) 方法分配的。

ZeroFreeCoTaskMemUTF8(IntPtr)	
释放非托管字符串指针,该指针是使用 StringToCoTaskMemUTF8(String) 方法分配的。

ZeroFreeGlobalAllocAnsi(IntPtr)	
释放非托管字符串指针,该指针是使用 SecureStringToGlobalAllocAnsi(SecureString) 方法分配的。

ZeroFreeGlobalAllocUnicode(IntPtr)	
释放非托管字符串指针,该指针是使用 SecureStringToGlobalAllocUnicode(SecureString) 方法分配的。

官网MSDN关于Marshal的介绍

五、 平台调用数据类型

下表列出了 Windows API 和 C 样式函数中使用的数据类型。 许多非托管库包含将这些数据类型作为参数和返回值传递的函数。 第三列列出了相应的 .NET Framework 内置值类型或可在托管代码中使用的类。 在某些情况下,用相同大小的类型替代表中列出的类型。

windows API中的非托管类型非托管C语言类型托管类型描述
VOIDvoidSystem.Void应用于不返回值的函数
HANDLEvoid *System.IntPtr或System.UIntPtr在32(64)位Windows操作系统上为32(64)位
BYTEunsigned charSystem.Byte8位
SHORTshortSystem.Int1616位
WORDunsigned shortSystem.UInt1616位
INTintSystem.Int3232位
UINTunsigned intSystem.UInt3232位
LONGlongSystem.Int3232位
BOOLlongSystem.Boolean 或 System.Int3232位
DWORDunsigned longSystem.UInt3232位
ULONGunsigned longSystem.UInt3232位
CHARcharSystem.Char使用ANSI修饰
WCHARwchar_tSystem.Char使用Unicode修饰
LPSTRchar *System.String 或 System.Text.StringBuilder使用ANSI修饰
LPCSTRconst char *System.String 或 System.Text.StringBuilder使用ANSI修饰
LPWSTRwchar_t *System.String 或 System.Text.StringBuilder使用Unicode修饰
LPCWSTRconst wchar_t *System.String 或 System.Text.StringBuilder使用Unicode修饰
FLOATfloatSystem.Single32位
DOUBLEdoubleSystem.Double64位

在这里解释一下System.IntPtr 该 IntPtr 类型设计为一个整数,其大小与指针相同。 也就是说,此类型的实例应在 32 位进程中为 32 位,在 64 位进程中为 64 位。

IntPtr 类型可由支持指针的语言使用,并作为引用执行和不支持指针的语言之间的数据的常见方法。

IntPtr 对象还可用于保存句柄。 例如,类中System.IO.FileStream广泛使用的IntPtr实例来保存文件句柄。

官网MSDN关于平台调用类型的介绍

有关 Visual Basic、C# 和 C++ 中的相应类型,请参阅 .NET Framework 类库简介。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值