zoukankan      html  css  js  c++  java
  • C#调用windowsAPI函数

    一 调用格式

    C#在调用windowsAPI函数接口的时候有一套专门的调用流程

    首先我们在调用API函数的时候必须引用命名空间InteropServices

    using System.Runtime.InteropServices;

    例如我们想调用windows的kernel32.dll动态库中的接口函数中的AllocConsole()控制台函数接口

    下面我们用最简单的调用形式来声明调用此函数接口(空方法,即方法体为空)

    [DllImport("kernel32.dll")]

    public static extern bool AllocConsole();

    下面我们可以用DllImportAttribute特性添加字段进一步说明

    1 CallingConvention

    指示向非托管实现传递方法参数时所用的CallingConvention值

    CallingConvention.Cded:调用方清理堆栈。他使用你能够调用具有varargs的函数

    CallingConvention.StdCall:被调用方清理堆栈。他是从托管代码调用非托管函数的默认约定

    2 CharSet

    控制调用函数的名称版本及指示如何向方法封送String参数

    CharSet.Ansi:所有字符串转换成ANSI字符串,同时向DLL EnterPoint的名称中追加字母”A“

    CharSet.Unicode:所有字符串参数在传递到非托管实现之前都转换成Unicode字符;向DLL EnterPoint的名称中追加字母"W"

    CharSet.Auto:这种转换就与平台有关(例如在windows NT上位unicode,而在windows 98上为Ansi)。

    CharSet的默认值为Ansi

    3 EnterPoint

    指示要调用的DLL入口点的名称或序号

    如果你的方法名不想与api函数同名的话,一定要指定此参数

    例如我想调用user32.dll中的MessageBox函数但是我想以自己的名字MsgBox名字来命名的话

    [DllImport("user32.dll",CharSet="CharSet.Auto",EnterPoint="MessageBox")]

    public static extern int MsgBox(IntPtr hWnd,string txt,string caption,int type);

    4 ExactSpelling

    指示是否应修改非托管DLL中的入口点的名称,与CharSet字段中指定的CharSet值相对应。

    如果为true,则当DllImportAttribute.CharSet字段设置为CharSet的Ansi值时,向方法名称中追加字母”A“,当DllImportAttribute.CharSet字段设置为CharSet的unicode值时,同方法名称中追加字母”W“,此字段的默认值为false

    5 PreserveSig

    指示托管方法签名不应该转换成返回HRESULT,并且可能有一个对应返回值的附加[out,retval]参数的非托管签名

    6 SerLastError

    指示被调用方法从属性化方法返回值之前调用win32 API SetLastError。

    true指示调用方将调用SetLastError,默认为false。运行时封送拆收器调用GetLastError并缓存返回的值,以防其他API调用重写。

    二 参数类型转换

    C++ C#
    DWORD int
    WORD Int16
    字符串指针类型 string
    句柄(handle、hWnd) IntPtr
    结构或者类 要先用StructLayout特性限定声明结构或类

    1 Explicit

    用于控制每个数据成员的精确位置。利用Explicit,每个成员必须使用FieldOffsetAttribute指示此字段在类型中的位置:

    [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;

    2 Sequential

    用于强制将成员按出现的顺序进行顺序布局

    例如针对API中的OSVERSIONINFO结构,在.net中定义类或者结构的例子如下

    API原型

    * API中定义原结构声明
    * OSVERSIONINFOA STRUCT
    * dwOSVersionInfoSize DWORD ?
    * dwMajorVersion DWORD ?
    * dwMinorVersion DWORD ?
    * dwBuildNumber DWORD ?
    * dwPlatformId DWORD ?
    * szCSDVersion BYTE 128 dup (?)
    * OSVERSIONINFOA ENDS
    *
    * OSVERSIONINFO equ <OSVERSIONINFOA>

    在.net中声明如下

    [ StructLayout( LayoutKind.Sequential )]
    public class OSVersionInfo
    {
    public int OSVersionInfoSize;
    public int majorVersion;
    public int minorVersion;
    public int buildNumber;
    public int platformId;
    [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]
    public String versionString;
    }

    注意:结构作为参数的时候,一般前面要加上ref修饰符,否则会出现错误:对象的引用没有指定对象的实例

    原文请访问:http://www.jb51.net/article/46041.htm

  • 相关阅读:
    类和对象系列教材 (十二)- 怎么写一个Java的饿汉式与懒汉式单例模式
    类和对象系列教材 (十二)- 怎么写一个Java的饿汉式与懒汉式单例模式
    [LeetCode] 285. Inorder Successor in BST
    [LeetCode] 671. Second Minimum Node In a Binary Tree
    [LeetCode] 230. Kth Smallest Element in a BST
    [LeetCode] 238. Product of Array Except Self
    [LeetCode] 273. Integer to English Words
    [LeetCode] 266. Palindrome Permutation
    [LeetCode] 409. Longest Palindrome
    [LeetCode] 124. Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/DannyShi/p/4604963.html
Copyright © 2011-2022 走看看