使用C#调用API函数






4.81/5 (38投票s)
2001 年 8 月 4 日
5分钟阅读

673260

9866
本文旨在帮助您了解如何在 C# 中调用 API 函数。
引言
API(应用程序编程接口)是一组命令,用于在程序与处理器之间进行接口。最常用的外部过程集是构成 Microsoft Windows 本身的功能。Windows API 包含数千个函数、结构和常量,您可以在项目中使用它们。但是,这些函数是用 C 语言编写的,因此在使用它们之前必须先声明它们。DLL 过程的声明可能会非常复杂。特别是对于 C# 来说,它比 VB 更复杂。您可以使用 API 查看器工具来获取 API 函数声明,但必须牢记参数类型,这在 C# 中有所不同。
大多数高级语言都支持 API 编程。Microsoft Foundation Class Library (MFC) 框架封装了 Win32 (API) 的大部分功能。ODBC API 函数对于在数据库上执行快速操作非常有用。通过 API,您的应用程序可以请求操作系统执行更低级别的服务。由于 API 支持从简单的消息框到加密或远程计算的数千种功能,因此开发人员应该知道如何在程序中实现 API。
API 有多种类型,具体取决于操作系统、处理器和功能。
特定于操作系统的 API
每个操作系统都有通用 API 和一些特殊 API。
例如:
Windows NT 支持 MS-DOS、Win16、Win32、POSIX(可移植操作系统接口)、OS/2 控制台 API;Windows 95 支持 MS-DOS、Win16 和 Win32 API。
Win16 和 Win32 API
Win16 是为 16 位处理器创建的 API,依赖于 16 位值。它具有平台无关性。
例如:您可以将 Win16 程序与 MS-DOS 功能(如 TSR 程序)绑定。
Win32 是为 32 位处理器创建的 API,依赖于 32 位值。它可以移植到任何操作系统、各种处理器,并且具有平台无关性。
Win32 API 在库名称后面带有“32”前缀,例如 KERNEL32、USER32 等。
所有 API 都使用 3 个库实现。
- 内核
- 用户
- GDI
1. KERNEL
它是名为 KERNEL32.DLL 的库,支持与操作系统相关的能力,例如:
- 进程加载。
- 上下文切换。
- 文件 I/O。
- 内存管理。
例如:GlobalMemoryStatus
函数获取有关系统当前物理内存和虚拟内存使用情况的信息。
2. USER
在 Win32 中,它是名为 USER32.DLL 的库。
它允许管理整个用户界面,例如:
- Windows
- 菜单
- 对话框
- 图标等。
例如:DrawIcon
函数在指定的设备上下文中绘制图标或光标。
3. GDI(图形设备接口)
在 Win32 中,它是名为“GDI32.dll”的库。它是图形输出库。使用 GDI,Windows 会绘制窗口、菜单和对话框。
- 它可以创建图形输出。
- 它还可以用于存储图形图像。
例如:CreateBitmap
函数创建一个具有指定宽度、高度和颜色格式(颜色平面和每像素位数)的位图。
C# 与 API
对于初学者来说,在 C# 中实现 API 是一项艰巨的任务。在实现 API 之前,您应该了解如何在 C# 中实现结构、类型转换、安全/不安全代码、托管/非托管代码等等。
在实现复杂 API 之前,我们将从简单的 MessageBox
API 开始。要实现 MessageBox
API 的代码,请打开一个新的 C# 项目并添加一个按钮。单击按钮时,代码将显示一个消息框。
由于我们正在使用外部库,因此请添加一个命名空间。
using System.Runtime.InteropServices;
添加以下几行来声明 API:
[DllImport("User32.dll")] public static extern int MessageBox(int h, string m, string c, int type);
这里使用 DllImport
属性来调用非托管代码中的方法。“User32.dll
”表示库名。DllImport
属性指定包含 extern
方法实现的 dll 位置。static
修饰符用于声明一个静态成员,该成员属于类型本身而不是特定的对象,extern
用于指示方法是在外部实现的。带有 DllImport
属性的方法必须具有 extern
修饰符。
MessageBox
是函数名,它返回 int
并接受 4 个参数,如声明所示。
许多 API 使用结构来传递和检索值,因为这样成本较低。它还使用常量数据类型来传递常量数据,并使用简单数据类型来传递内置数据类型,如先前的 MessageBox 函数声明所示。
为按钮单击事件添加以下代码:
protected void button1_Click(object sender, System.EventArgs e) { MessageBox (0,"API Message Box","API Demo",0); }
编译并运行项目,单击按钮后,您将看到一个消息框,这是您通过 API 函数调用的!
使用结构
使用包含复杂结构或嵌套结构的 API 比使用简单 API 要复杂一些。但是,一旦您理解了实现方法,整个 API 世界就属于您了。
在下一个示例中,我们将使用 GetSystemInfo
API,它返回有关当前系统的[]信息。
第一步是打开一个新的 C# 窗体并在其上添加一个按钮。转到窗体的代码窗口并添加一个命名空间。
using System.Runtime.InteropServices;
声明作为 GetSystemInfo
参数的结构。
[StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { public uint dwOemId; public uint dwPageSize; public uint lpMinimumApplicationAddress; public uint lpMaximumApplicationAddress; public uint dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public uint dwProcessorLevel; public uint dwProcessorRevision; }
声明 API 函数。
[DllImport("kernel32")] static extern void GetSystemInfo(ref SYSTEM_INFO pSI);
其中 ref
紧跟在方法参数关键字后面,它会导致方法引用传递给方法的同一个变量。
在按钮单击事件中添加以下代码,我们首先创建一个 struct 对象,然后将其传递给函数。
protected void button1_Click (object sender, System.EventArgs e) { try { SYSTEM_INFO pSI = new SYSTEM_INFO(); GetSystemInfo(ref pSI); // // //
检索到结构后,对所需参数执行操作。
例如:listBox1.InsertItem (0,pSI.dwActiveProcessorMask.ToString());
// // // } catch(Exception er) { MessageBox.Show (er.Message); } }
在附加代码中,我使用了两个 API 来检索系统中的各种信息。
注意
我使用了 Beta 版 1.0 来创建示例应用程序。在 Beta 2 中,API 函数的声明可能与 1.0 版略有不同。