C#調用windowsAPI函數

來源:互聯網
上載者:User

標籤:

一 調用格式

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:被呼叫者清理堆棧。他是從Managed 程式碼調用非託管函數的預設約定

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

C#調用windowsAPI函數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.