1. Windows内核对象
l 内核对象:存取符号对象、事件对象、文件对象、文件映射对象、I / O完成端口对象、作业对象、信箱对象、互斥对象、管道对象、进程对象、信标对象、线程对象和等待计时器对象;
l 用户对象或GDI对象:菜单、窗口、鼠标光标、刷子和字体。
用于创建用户对象或G D I对象的函数都没有P S E C U R I T Y _ AT T R I B U T E S参数,创建内核对象的所有函数几乎都有一个P S E C U R I T Y _ AT T R I B U T E S参数,用来设置安全属性的信息
(windows核心编程)
2. 跨进程共享内核对象
l 对象句柄的继承性、父/子进程的继承性;
l 命名内核对象:为内核对象提供一个name,Create对应Open;
l 复制对象句柄:DuplicateHandle。
(windows核心编程)
3. Windows API中所有的函数都包含在DLL中,其中3个最重要的DLL:
l Kernel32.dll,包含哪些用于管理内存、进程和线程的函数;
l User32.dll,包含那些用于执行用户界面任务的函数(如窗口的创建和消息的传送);
l GDI32.dll,包含那些用于画图和显示文本的函数。
(VC++深入详解)
4. 动态库和静态库
l 静态库:二进制文件(通常为.lib),使用的时候复制静态库的函数和数据到exe文件中,发布产品时只需要exe,不需要使用的静态库;
l 动态库:往往有两个文件,引入库(.lib)文件和DLL文件(.dll),引入库文件包含该DLL导出的函数和变量的符号,DLL文件包含实际的函数和数据。动态库是运行时加载,映射到进程的地址空间中,然后访问DLL中导出的函数,发布产品时除了exe文件外还需要该动态库。
(VC++深入详解)
5. 动态库的加载
l 隐式链接
需要知道DLL中函数的声明,在使用前利用extern声明外部函数,在项目属性的”Object/library modules”中输入该DLL文件名,同时需要将该DLL文件拷贝到程序的执行目录(或当前目录或系统目录(C:/WINNT/system32,C:/WINNT/system,C:/WINNT)或path环境变量中所列出的路径)
比如:一个简单的add函数
在dll.cpp中的代码:
_declspec(dllexport) int add(int a,int b)
{ return a+b; }
在使用的文件中声明为:
extern int add(int a,int b);
或者:
_declspec(dllimport) int add(int a,int b); //目的就是告诉编译器该函数 //是从动态链接库中引入的。
或者,为了让别的使用者也知道DLL中有该函数,提供一个头文件dll.h,在头文件里声明函数:
_declspec(dllimport) int add(int a,int b);
然后在dll.cpp文件中包含头文件就行了。
l 显式链接(动态方式)
显式的方式不用在工程属性设置里的Link选项卡中队DLL文件的链接,也不用包含dll头文件。动态方式先用LoadLibrary函数将制定的可执行模块映射到调用进程的地址空间:
HMODULE LoadLibrary( LPCTSTR lpFileName);
获取到动态链接库模块的句柄后,调用函数获取该动态链接库中导出函数的地址:
FARPROC GetProcAddress( HMODULE hModule, LPSCTR lpProcName);
这样得到的是个函数指针,其中可以根据函数名或者序号来寻找导出函数。
(VC++深入详解)
6. dll相关工具
l Visual Studio命令行工具:Dumpbin
Dumpbin –export dllname.dll 查看一个DLL文件的导出函数
也能查看exe可执行程序的输入信息以及其加载的DLL信息:
Dumpbin –imports dllname.exe
l Visual Studio6 Depends工具:查看一个模块(可执行或者DLL)依赖的动态链接库
(VC++深入详解)