BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / dot-net / #5同步于 2009/11/27
该镜像源已超过 30 天没有更新,可能在源站已被删除。
dotNET机器人发帖

[范文].NET程序中如何调用win32 API (转载)

haibara
2009/11/27镜像同步10 回复
【 以下文字转载自 Board_Apply 讨论区 】 发信人: ahomer (水上蓝心), 信区: Board_Apply 标 题: [范文].NET程序中如何调用win32 API 发信站: 北邮人论坛 (Thu Nov 19 13:36:40 2009), 站内 Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微软留给我们直接控制Windows的接口。想玩儿吗?呵呵,太难了。 C#使用非常简单,写程序就像打拱猪,Sorry -_-! ,搭积木一样简单。想玩儿吗?呵呵,没办法直接控制Windows的核心。 难道就没有两全其美的办法吗?当然不是!要不微软的产品早就没人买了。其实从C#(或者说.NET平台)调用Win32 API还是非常简单滴~~~~今天偶们大家就一起来研究研究。 Win32 API是C语言(注意,不是C++语言,尽管C语言是C++语言的子集)函数集。C#语言与C语言是完全不同的(除了语法上比较像),所以,要想用C#语言调用C语言的Win32 API,要费上一番周折。首先我们就要准备一些基础知识。 Win32 API函数是Windows的核心,比如我们看到的窗体、按钮、对话框什么的,都是依靠Win32函数“画”在屏幕上的,由于这些控件(有时也称组件)都用于用户与Windows进行交互,所以控制这些控件的Win32 API函数称为“用户界面”函数(User Interface Win32 API),简称UI函数;还有一些函数,并不用于交互,比如管理当前系统正在运行的进程、硬件系统状态的监视等等……这些函数只有一套,但是可以被所有的Windows程序调用(只要这个程序的权限足够高),简而言之,API是为程序所共享的。为了达到所有程序能共享一套API的目的,Windows采用了“动态链接库”的办法。之所以叫“动态链接库”,是因为这样的函数库的调用方式是“随用随取”而不是像静态链接库那样“用不用都要带上”。 这里不太好理解,不要紧,我们举个小例子。我们把Windows比做一个游乐场,而把在游乐场里玩儿的小孩比做一个一个程序。小孩在玩的过程中可能要喝水。我们有两个办法让小家伙们想喝水的时候就有水喝:1.给每个小家伙配一个水壶,小家伙们喝了的话就喝自己带的水;2.给游乐场配一个饮水机,谁渴了谁来喝。显然,第二个方法要好得多,这体现在三个地方。第一,带着水壶,小家伙身体不灵活、玩不爽(影响程序的速度),况且这只是带了一个水壶,要是再带上饭盒呢?还有轮滑、头盔、创可贴、纱布……AK-47 My God,如果带全了就赶上美国大兵了。所以游乐园里还是有个公用“仓库”要来的方便,让大家随用随取(动态链接)。第二,小家伙们带了那么多东西,占了游乐场很多地方,让游乐场拥挤不堪,别的小朋友就进不来了(程序体积大,影响程序和系统的性能)。第三,如果某件物品升级了,比如水壶从一升的改为二升的,那么每个小家伙就必须go home去换新的(重新编译程序,由编译器把新的静态库链接进程序主体里),而第二种情况里,只要游乐场把自己仓库里的水壶换个型号,那么所有小家伙就都在同一时间拥有了大容量的水壶。(悟空!我就一会儿不在,你怎么就乱丢东西?!打到小朋友多不好~~~~~) 悟空已经急了,我就不再叽叽歪歪了……呃……Win32 API函数是放在Windows系统的核心库文件中的,这些库在硬盘里的存储形式是.dll文件。我们常用到的dll文件是user32.dll和kernel32.dll两个文件,还有其它一些dll文件也非常重要,大家要在实践中多积累经验。 我们知道Win32 API函数是放在dll文件中了,但新问题又来了——我们怎么调用它们呢?这些dll文件是用C语言写的,源代码经C语言编译器编译之后,会以二进制可执行代码形式存放在这些dll文件中,就好像苹果被打碎机打成果酱后装在罐子里一样——你再也分不清哪个是你GF给你的,哪个是你老妈给你的一样。为了能让程序使用这些函数,微软在发布每个新的操作系统的时候,也会放出这个系统的SDK,目前最新的是Win2003 SP1 SDK,据说Vista的马上就要放出来,而且已经把UI的API从核心库中分离出去以提高系统的稳定性了。SDK里有一些C语言的头文件(.h文件),这些文件里描述了核心dll文件里都有哪些Win32 API函数,在写程序的时候,把这些.h文件用#include"....."指令包含进你的程序里,你就可以使用这些Win32 API了。至于程序是怎样链接的,超出了本文的范围——也超出了本人的知识范围:D 至此,如果你是C语言高手,已经可以使用Windows SDK去调教Windows了!不过,今天我们讨论的是C#语言调用Win32 API的问题。我们现在已经知道API函数放在dll动态链接库文件里,也知道C语言怎么调用它们了,那么C#语言怎么办呢?C#语言是不能使用C语言的.h文件的。C#语言也使用dll动态链接库,不过这些dll都是.NET版本的,具有“自描述性”,也就是自己肚子里都有哪些函数都已经写在自己的metadata里了,不用再附加一个.h文件来说明。现在,我们已经找到了问题的关键点:如何用.NET平台上的C#语言来调用Win32平台上的dll文件。答案非常简单:使用DllImport特性。
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
Thinker机器人#1 · 2009/11/28
好文! 果然不愧是范文! 读后拍案叫绝! [em22]
univer机器人#2 · 2009/11/29
嗯~ C# 和 C API的操作主要有三种方式。 1. P/Invoke,也就是上文中提到的方式,用DllImport特性标注方法声明。 2. 托管C++封装,在底层C++的函数的参数或返回值是复杂类型或结构体时,可以大大减少Marshal带来的通信量,也大大减少代码量。 3. COM,将C++封装为COM接口,C#可以直接进行调用。 【 在 haibara 的大作中提到: 】 : 发信人: ahomer (水上蓝心), 信区: Board_Apply : 标 题: [范文].NET程序中如何调用win32 API : 发信站: 北邮人论坛 (Thu Nov 19 13:36:40 2009), 站内 : ...................
ahomer机器人#3 · 2009/11/29
呵呵,对~ 这个《精通.NET互操作》那本书讲得很清楚 【 在 univer (Univer) 的大作中提到: 】 : 嗯~ : C# 和 C API的操作主要有三种方式。 : 1. P/Invoke,也就是上文中提到的方式,用DllImport特性标注方法声明。 : ...................
speeter机器人#4 · 2009/11/30
学习~
gazi210机器人#5 · 2009/12/4
不错,顶一下
ericyosho机器人#6 · 2009/12/5
怎么看也没觉得LZ已经写完了@@
denggang0828机器人#7 · 2009/12/11
3 通过PIA调用吧? 【 在 univer 的大作中提到: 】 : 嗯~ : C# 和 C API的操作主要有三种方式。 : 1. P/Invoke,也就是上文中提到的方式,用DllImport特性标注方法声明。 : ...................
youzidieyi机器人#8 · 2009/12/11
using System; using System.Runtime.InteropServices; class MainClass { [DllImport("User32.dll")] public static extern int MessageBox(int h, string m, string c, int type); static int Main() { string myString; Console.Write("Enter your message: "); myString = Console.ReadLine(); return MessageBox(0, myString, "My Message Box", 0); } }
snoopyboy机器人#9 · 2009/12/11
? 【 在 youzidieyi (幽紫蝶衣) 的大作中提到: 】 : using System; : using System.Runtime.InteropServices; : class MainClass : ...................