• 第十九章 DLL基础


    //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
    ");
    }
    
    int nValue = 1024;
    
    void CTest::ClassFun()
    {
    	printf("ClassFun
    "); 
    }
    
    //可执行项目:
    #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与其他厂家的工具包构建的可执行文件链接,需要做额外的工作,过程:略,详情见书
    

      

  • 相关阅读:
    第十四周学习进度
    团队十日冲刺17
    团队十日冲刺16
    找水王
    搜狗输入法评价
    团队十日冲刺15
    团队十日冲刺14
    团队十日冲刺13
    团队十日冲刺12
    团队十日冲刺11
  • 原文地址:https://www.cnblogs.com/szn409/p/8542165.html
Copyright © 2020-2023  润新知