一、Intro尝试
C#中的API就是Win32API,即平台调用(P/Invoke),一种调用非托管的DLL中函数的.net特性。
Windows API 是作为 Windows 操作系统一部分的动态链接库 (DLL)。当难以自己编写等效的过程时,可以使用它们来执行任务。
在代码中使用 Windows API 的好处在于它们可以节省开发时间,因为它们包含许多已经编写好的、等待使用的有用函数。缺点是在发生故障时,Windows API 可能难以处理并且不可挽回。
尝试的程序:
Windows API 表示一种特殊类别的互操作性。Windows API 不使用托管代码,不具备内置类型库,它使用的数据类型与 Visual Studio 中所用的数据类型不同。由于这些差别,且 Windows API 不是 COM 对象,所以与 Windows API 和 .NET Framework 的互操作是通过使用平台调用 (PInvoke) 来完成的。平台调用是一种服务,它使托管代码能够调用 DLL 中实现的非托管函数。。。
平台调用是一种服务,它使托管代码能够调用 DLL 中实现的非托管函数
如调用系统的 API 或与 COM 对象打交道,通过 System.Runtime.InteropServices 命名空间
为了从托管代码中调用非托管的DLL中函数,我们要创建一个P/Invoke包装。
其实用来创建P/Invoke包装的语法与创建托管方法的声明语法本质上是一样的。唯一不同是P/Invoke包装不包含函数体,而只有方法 名、返回值类型和参数信息。
二、Beep程序
Win32 API 集非常庞大。他们没有足够的资源为所有 Win32 API 编写托管接口、加以测试并编写文档,因此只能优先处理最重要的部分。
许多常用操作都有托管接口,但是还有许多完整的 Win32 部分没有托管接口。
C#调用P/Invoke是完成这一任务的最常用方法。要C#调用P/Invoke,要编写一个描述如何调用函数的原型,然后运行时将使用此信息进行调用。
另一种方法是使用 Managed Extensions to C++ 来包装函数。。
在Beep的尝试中:
可以查到:
MSDN 中的定义,我发现它具有以下原型:
- BOOL Beep{
- DWORD dwFreq, // 声音频率
- DWORD dwDuration // 声音持续时间
- }
若用C# 来编写这一原型,需要将 Win32 类型转换成相应的 C# 类型。由于 DWORD 是 4 字节的整数,因此我们可以使用 int 或 uint 作为 C# 对应类型。
又由于 int 是 CLS 兼容类型(可以用于所有 .NET 语言),以此比 uint 更常用,bool 类型与 BOOL 对应。
程序实现:
成功实现了随机生成的Beep音播放~