动/静态库

1    动态连接库/静态连接库
 

1.1    动态库.dll.ocx.cpl
    动态库在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题(引用技术),只需要更新动态库,增量更新。
    动态库不能直接运行,也不能接收消息。它们是一些独立的文件,其中包含能被可执行程序或其它DLL调用来完成某项工作的函数或是数据。只有在其它模块调用动态链接库中的函数时,它才发挥作用。
    动态库的引入库.lib与静态库明本质区别,引入库包含动态库导出的函数声明和变量名的符号,动态库包含实际函数定义和数据。
    发布时提供引入库和动态库。

    Windows API中的所有函数都包含在DLL中。其中有3个最重要的DLL,
    Kernel32.dll,它包含用于管理内存、进程和线程的各个函数;
    User32.dll,它包含用于执行用户界面任务(如窗口的创建和消息的传送)的各个函数;
    GDI32.dll,它包含用于画图和显示文本的各个函数。

    动态库需要一个DllMain函数做出初始化的入口。对于一个Dll模块,DllMain函数是可选的。
 

    #define DLL_PROCESS_ATTACH   1    
    DLL文件首次被映射到进程空间。    

    #define DLL_THREAD_ATTACH    2    
    进程每次建立新线程,哪怕是在线程中建立线程。

    #define DLL_THREAD_DETACH    3     
    线程调用 ExitThread 。线程级清理工作。
注意,调用 TerminateThread 不会调用 DLL_THREAD_DETACH。

    #define DLL_PROCESS_DETACH   0
    DLL文件被从进程的地址空间解除映射。进程级清理工作。
解除情形一,FreeLibrary(有几个LoadLibrary,就要有几个FreeLibrary)。
解除情形二,进程结束。
注意,调用 TerminateProcess 不用调用 DLL_PROCESS_DETACH。若 DLL_PROCESS_ATTACH 返回失败,退出时也会调用 DLL_PROCESS_DETACH。

      
1.1.1        导出方式

    方式一,在要导出的函数或变量名前加上 extern "C" _declspec(dllexport),extern "C"只能导出全局函数或全局变量 
 
    

    方式二,把要导出的函数名称或变量名添加到导出文件 .def 
.cpp
  
.def
 
项目属性-配置属性-链接器-命令行-附加选项 /DEF:?.def


1.1.2        使用方式
    方式一,隐式加载(使用.def不能以隐式导出函数)
 
 



    方式二,显式加载
 
 
 



1.2    静态库.lib
    链接时,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中,对应的链接方式称为静态链接,得到静态连接库。
    静态库对函数库的链接是放在编译时期完成的,程序在运行时与函数库再无瓜葛,移植方便,但体积大,浪费空间(每个使用到该库的文件在磁盘都有其副本,运行时在内存都有其副本),更新时需要重新编译。
    发布时提供可执行文件即可。

    创建静态库,Win32项目 - 静态库

    使用静态库, 
#include  “../?.h”
#pragma comment(lib, "?.lib")

 
1.3    配置x64编译选项
    加载现在或新建项目,选中项目
    生成--配置管理器--
    活动解决方案平台--新建--
    键入或选择新平台--下拉选择x64,从此处复制选择已有的Win32,确定完成
32bit程序/64bit程序分别选择Win32/x64选项编译即可。
    需要注意的是,x64下数据类型的使用。
    通过使用 Windows typedef 类型而非 C++ 编译器的本机类型(intlong 等),Windows 头使得编写干净的 Win32 x64 代码很轻松。
    最常见而简单的错误可能就是:假定指针值可以存储或传递到 32 位类型(如 intlong)甚至 DWORD 中。解救方法是 Windows 头中定义的 _PTR 类型。DWORD_PTR、INT_PTR 和 LONG_PTR 之类的类型可让您声明整数类型的变量,并且这些变量始终足够长以便在目标平台上存储指针。例如,定义为 DWORD_PTR 类型的变量在针对 Win32 编译时是 32 位整数,在针对 Win64 编译时是 64 位整数。
    另一个问题是 printf 和 sprintf 格式化。不再使用 %X 或 %08X 格式化指针值,正确的方法是使用 %p,%p 可以在目标平台上自动考虑指针大小。此外,对于与大小相关的类型,printf 和 sprintf 还具有 I 前缀。例如,可使用 %Iu 来打印 UINT_PTR 变量。同样,如果知道该变量始终是 64 位标记值,则可以使用 %I64d。

 

posted on 2016-11-02 17:33  NoneButNow  阅读(258)  评论(0编辑  收藏  举报

导航