C#调用Win32 api学习总结
从.NET平台调用Win32 API
Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微软留给我们直接控制Windows的接口。
一. 基础知识
Win32 API是C语言(注意,不是C++语言,尽管C语言是C++语言的子集)函数集。
1. Win32 API函数放在哪里?
Win32 API函数是Windows的核心,比如我们看到的窗体、按钮、对话框什么的,都是依靠Win32函数“画”在屏幕上的,由于这些控件(有时也称组件)都用于用户与Windows进行交互,所以控制这些控件的Win32 API函数称为“用户界面”函数(User Interface Win32 API),简称UI函数;还有一些函数,并不用于交互,比如管理当前系统正在运行的进程、硬件系统状态的监视等等……这些函数只有一套,但是可以被所有的Windows程序调用(只要这个程序的权限足够高),简而言之,API是为程序所共享的。为了达到所有程序能共享一套API的目的,Windows采用了“动态链接库”的办法。之所以叫“动态链接库”,是因为这样的函数库的调用方式是“随用随取”而不是像静态链接库那样“用不用都要带上”。
Win32 API函数是放在Windows系统的核心库文件中的,这些库在硬盘里的存储形式是.dll文件。我们常用到的dll文件是user32.dll和kernel32.dll两个文件。
这些dll文件是用C语言写的,源代码经C语言编译器编译之后,会以二进制可执行代码形式存放在这些dll文件中。为了能让程序使用这些函数,微软在发布每个新的操作系统的时候,也会放出这个系统的SDK,目前最新的是Win2003 SP1 SDK,据说Vista的马上就要放出来,而且已经把UI的API从核心库中分离出去以提高系统的稳定性了。SDK里有一些C语言的头文件(.h文件),这些文件里描述了核心dll文件里都有哪些Win32 API函数,在写程序的时候,把这些.h文件用#include"....."指令包含进你的程序里,你就可以使用这些Win32 API了。
C#语言也使用dll动态链接库,不过这些dll都是.NET版本的,具有“自描述性”,也就是自己肚子里都有哪些函数都已经写在自己的metadata里了,不用再附加一个.h文件来说明。现在,我们已经找到了问题的关键点:如何用.NET平台上的C#语言来调用Win32平台上的dll文件。答案非常简单:使用DllImport特性。
二. 小试
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
static int Main()
{
MessageBox(0, "Hello Win32 API", "大爷", 4);
Console.ReadLine();
return 0;
}
}
1. 要使用DllImport这个特性(特性也是一种类),必须使用这一句using System.Runtime.InteropServices;
,导入“运行时->交互服务”。喔~~~~运行时的交互服务不就是“动态链接”吗?感谢Microsoft!
2. 然后我们就可以制造一个DllImport类的实例,并把这个实例绑定在我们要使用的函数上了。“特性类”这种类非常怪——制造类实例的时候不使用MyClass mc = new MyClass();这种形式,而是使用[特性类(参数列表)]这种形式;特性类不能独立存在,一定要用作修饰其它目标上(本例是修饰后面的一个函数),不同的特性可以用来修饰类、函数、变量等等;特性类实例在被编译的时候也不产生可执行代码,而是被放进metadata里以备检索。总之,你记住特性类很怪就是了,想了解更多就查查MSDN,懒得查就先这么记——不懂惯性定律不影响你学骑自行车。[DllImport("User32.dll")]是说我们要使用的Win32 API函数在User32.dll这个文件里。问题又来了:我怎么知道那么多API函数都在哪个dll文件里呢?这个你可以在MSDN里查到,位置是Root->Win32 and COM Development->Development Guides->Windows API->Windows API->Windows API Reference->Functions by Category。打开这页,你会看到有很多API的分类,API全在这里了。打开一个分类,比如Dialog Box,在Functions段,你会看到很多具体的函数,其中就有上面用到的MessageBox函数,点击进入。你将打开MessageBox的详细解释和具体用法。在这一页的底部,你可以看到一个小表格,里面有一项“Minimum DLL Version user32.dll”就是说这个函数在user32.dll里。
3. 接下来就是我们的函数了。在C#里调用Win32函数有这么几个要点。第一:名字要与Win32 API的完全一样。第二:函数除了要有相应的DllImport类修饰外,还要声明成public static extern类型的。第三:函数的返回值和参数类型要与Win32 API完全一致!
从MSDN里摘出一张表来,是常用Win32数据类型与.NET平台数据类型的对应表:
Figure 2 Non-Pointer Data Types
Win32 Types Specification
CLR Type
char, INT8, SBYTE, CHAR 8-bit signed integer
System.SByte
short, short int, INT16, SHORT 16-bit signed integer
System.Int16
int, long, long int, INT32, LONG32, BOOL, INT 32-bit signed integer System.Int32
__int64, INT64, LONGLONG 64-bit signed integer
System.Int64
unsigned char, UINT8, UCHAR, BYTE 8-bit unsigned integer
System.Byte
unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR, __wchar_t
16-bit unsigned integer System.UInt16
unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT
32-bit unsigned integer System.UInt32
unsigned __int64, UINT64, DWORDLONG, ULONGLONG 64-bit unsigned integer System.UInt64
float, FLOAT Single-precision floating point
System.Single
double, long double, DOUBLE Double-precision floating point
System.Double
In Win32 this type is an integer with a specially assigned meaning; in contrast, the CLR provides a specific type devoted to this meaning.
有了这些东西,我们就能把一个Win32 API函数转成C#函数了。还拿MessageBox函数为例(看刚才给出的函数表),它的Win32原形如下:
int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );
函数名:MessageBox将保持不变。
返回值:int 将保持不变(无论是Win32还是C#,int都是32位整数)
参数表:H开头意味着是Handle,一般情况下Handld都是指针类型,Win32平台的指针类型是用32位来存储的,所以在C#里正好对应一个int整型。不过,既然是指针,就没有什么正负之分,32位都应该用来保存数值——这样一来,用uint(无符号32位整型)来对应Win32的H类型更合理。不过提醒大家一点,int是受C#和.NET CLR双重支持的,而uint只受C#支持而不受.NET CLR支持,所以,本例还是老老实实地使用了int型。
至于LPCTSTR是Long Pointer to Constant String的缩写,说白了就是——字符串。所以,用
http://m.blog.csdn.net/article/details?id=50930221
C#调用Win32 api学习总结的更多相关文章
- MSIL 教程(二):数组、分支、循环、使用不安全代码和如何调用Win32 API(转)
转自:http://www.cnblogs.com/Yahong111/archive/2007/08/16/857574.html 续上文[翻译]MSIL 教程(一) ,本文继续讲解数组.分支.循环 ...
- Python调用win32 API绘制正弦波
Python调用win32 API新建窗口与直接创建窗口的流程相同 流程:注册窗口→创建窗口→显示窗口→更新窗口→消息循环 代码: # -*- coding: utf-8 -*- import win ...
- C#调用Win32 api时的内存操作
一般情况下,C#与Win 32 Api的互操作都表现的很一致:值类型传递结构体,一维.二维指针传递IntPtr.在Win32 分配内存时,可以通过IntPtr以类似移动指针的方式读取内存.通过IntP ...
- nodejs 调用win32 api
video 教程文件 win32 api >node -v v12.16.1 >npm install -g node-gyp >npm i @saleae/ffi >node ...
- 调用win32 api 函数SendMessage() 实现消息直接调用
简单的调用例子, 适合初学者学习,当然 我也是初学者. #include <windows.h> #include <stdio.h> #include <stdlib. ...
- C#调用win32 api 操作其它窗口
实现以下功能: 找到窗体 找到控件(也叫子窗体) 获取内容 获取位置 设置 位置 内容 鼠标点击 示范 1. 找窗体 以操作系统自带的计算器为例 string clWindow = "Cal ...
- C#调用win32 api程序实例
1.声明static extern 方法,使用DllImport特性 class MyClass { [DllImport("kernel32", SetLastError = t ...
- win32 API 学习
SendMessage 函数原型 LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam) 详情:百度百科 msd ...
- Win32+API学习笔记:创建基本的窗口控件
创建一个标签 CreateWindowEx(0, "static", "姓名:", ...
随机推荐
- php 文件上传简单类---限制仅上传jpg文件
php 文件上传代码,限制只能上传jpg格式文件,也可以自行添加其它扩展名的文件. <?php /* * 图片上传类 仅限JPG格式图片 * edit by www.jbxue.com at 2 ...
- this.IsMounted() is not a function
I'm trying to build a simple React App. It retrieves data from an ajax call and renders it to the pa ...
- IO多路转接select和poll
select IO多路复用的设置方法与信号的屏蔽有点相似: 信号屏蔽需要先设定一个信号集, 初始化信号集, 添加需要屏蔽的信号, 然后用sigprocmask设置 IO多路转接需要先设定一个文件描述符 ...
- Fat-tree 胖树交换网络
胖树架构下,网络带宽不收敛 传统的树形网络拓扑中,带宽是逐层收敛的,树根处的网络带宽要远小于各个叶子处所有带宽的总和. 而胖树网络则更像是真实的树,越到树根,枝干越粗,即:从叶子到树根,网络带宽不收敛 ...
- python之字串
python字串声明: 单引('), 双引("), 三引(''' 或 """"). python字串前缀: r表示原生字串, 字串内容: (1)不能包 ...
- nginx学习之一
http://tengine.taobao.org/book/chapter_02.html
- WPF解析PPT为图片
偶遇需要解析 PPT为单张图片 其中,对于包含动画的PPT页,分别对动画最后效果进行截取,即每个连续动画截取 (动画N个)N+1(原图)张 http://git.oschina.net/jiailiu ...
- adb 选择设备
在adb中有多个设备时,可以先adb devices列举出设备,然后可以通过adb -s <设备名> [其他参数] 对某个设备进行操作. 例如: adb -s 0123456789ABC ...
- Source Insight中文操作支持的宏
以下是Source Insight中文字符串支持的宏的实现,在此做个备份. 代码来自网上,非笔者所写.原有代码有个明显的Bug(Del的时候会导致多删除一个字符和多插入一个空格),已经被笔者fix掉. ...
- [C#]Linq To Xml 介绍- 转
LINQ to XML 类概述 LINQ to XML 旨在使 XML 名称尽可能简单. XAttribute 类 XAttribute 表示一个 XML 属性. XCData 类 XCDat ...