65.9K
CodeProject 正在变化。 阅读更多。
Home

使用C#调用API函数

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (38投票s)

2001 年 8 月 4 日

5分钟阅读

viewsIcon

673260

downloadIcon

9866

本文旨在帮助您了解如何在 C# 中调用 API 函数。

Sample Image - usingAPI.gif

引言

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 版略有不同。

© . All rights reserved.