代码改变世界

第十九章 DLL基础

2018-03-10 21:33  szn好色仙人  阅读(163)  评论(0编辑  收藏  举报
//1.
DLL构建:选择 Win32 控制台应用程序 -> DLL(附加选项里 勾选上 空项目)

//2.
Windows 应用程序编程入口(API)提供的所有函数都包含在DLL中。其中三个最重要的DLL:
Kernel32.dll:包含的函数用来管理内存、进程以及线程
User32.dll:包含的函数用于执行与界面相关的任务
GDI32.dll:包含的函数用来绘制图像和显示文字

//3.
(A):DLL通常由一组可供任何应用程序使用的独立函数组成。在DLL中通常不包含处理消息循环或创建窗口的代码
(B):在创建DLL的时候,必须给编译器指定 /DLL 开关
(C):在应用程序能调用一个DLL里的函数前,必须将该DLL的文件映像映射到调用进程的地址空间中:隐式载入时链接、显示运行时链接
(D):系统一旦将一个DLL文件映射到调用进程的地址空间后,进程中所有的线程就可以正常调用该DLL中的函数了
(E):DLL中若提供了分配资源的接口,一定也要提供释放资源的接口。若DLL将资源释放的接口留给可执行文件,那么可执行文件可能链接不同版本DLL造成问题
比如:DLL实现了一个函数返回动态分配的内存的指针,则此指针最好不要由可执行文件中的代码去管理

//4.
构建DLL步骤:
(A):必须创建一个头文件,在其中包含我们想在DLL中导出的函数原型、结构、符号。为了构建DLL,DLL的所有源文件必须包含此头文件。在构建可执行文件的时候也需要此头文件
(B):创建源文件来实现想在DLL中导出的函数和变量。构建可执行文件的时候并不需要这些源文件
(C):构建DLL模块时,编译器会对每个源文件生成一个.obj模块
(D):当所有.obj模块创建完成后,链接器会将所有.obj模块的内容合并起来,产生一个单独的DLL镜像文件。这个镜像文件包含DLL中所有二进制代码以及全局/静态变量
(E):如果链接器检测到DLL的源文件输出了至少一个函数或变量,那么链接器还会生成一个.lib文件,此文件包含了所有被导出的函数和变量的符号名,构建可执行文件时候需要此文件

//5.
(A):应避免从DLL中导出变量,因为这样会破坏封装性,使得DLL难以维护
(B):只有当导出C++类的模块使用的编译器与导入C++类的模块使用的编译器是同一厂商提供的,我们才能导出C++类,否则应避免导出C++类
(C):DLL与可执行文件应该使用同一个头文件,这样才利于代码的维护
(D):如果编译器看到一个变量、函数或C++类是用 __declspec(dllexport) 修饰的,那么他就知道应该在生成的DLL模块导出该变量、函数或C++类
(E):extern "C" 修饰符:在编写C++代码的时候应该使用这个修饰符,在编写C代码的时候不应该使用此修饰符。C++编译器通常会对函数名和变量名进行改编,这会在链接的时候导致问题
(F):__declspec(dllimport) 让编译器知道可执行文件需要从DLL模块导入哪些变量或函数
(G):DumpBin.exe /exports 可以查看DLL的导出段
(H):
DLL例子:
//DLL项目:Tool.h
#pragma once

#ifndef SznDllTest
#define SznDllTest __declspec(dllimport)
#endif

extern "C" SznDllTest void FunTest();

extern "C" SznDllTest int nValue;

class SznDllTest CTest
{
public:
	CTest(){}

public:
	void ClassFun();
};

//DLL项目:Tool.cpp
#define SznDllTest __declspec(dllexport)
#include "Tool.h"
#include <cstdio>

void FunTest()
{
	printf("FunTest\n");
}

int nValue = 1024;

void CTest::ClassFun()
{
	printf("ClassFun\n"); 
}

//可执行项目:
#include "Tool.h"

#pragma comment(lib, "Test.lib")

int main()
{
	FunTest();			//输出FunTest
	int nTem = nValue;	//nTem = 1024
	CTest Test;			//输出ClassFun
	Test.ClassFun();
	return 0;
}

//6.
如果用 Microsoft virtual C++ 创建的DLL与其他厂家的工具包构建的可执行文件链接,需要做额外的工作,过程:略,详情见书