非MFC的DLL[转载](待消化)

非MFC的DLL

1.DLL与extern  "C" 的关系
  当在生成动态链接库(DLL)的时候,如果采用extern "C" 语句,则告知编译器采用c链接的方式 ,结果是生成的DLL的对外部接口(函数)的名字不加处理,在动态加载(loadlibrary ,getprocaddress,freelibrary )语句的时候可以直接通过函数名字来找到此函数在DLL中的入口。
  如果不采用extern  "C"语句声明dll外部函数的时候,则编译器采用C++的链接方式,将对函数名做些处理(一般是函数名的前面加"?",后面加几个大写字母和@),这样 在动态加载该DLL通过getprocaddress语句通过函数名来得到函数在DLL的入口地址时就会出问题,导致调用失败。但是,采用C++链接方式 的时候,可以用静态链接的方式来避免此问题,即是将与动态链接库一块生成的lib文件一块拷到被调用的工程中,在需要调用该dll文件的时候 用#prama comment(lib,"…….lib")语句或者在工程同修改编译连接选项的方式来静态加载DLL,此后就可以像调用文件内部的函数通过名字来调用 dll中的外部函数了。

2.DLL与对应头文件的关系
  首先要理解.h头文件的作用,由于头文件的作用只是为了声明函数、宏定义等目的,编译器编译的单位是每一个.cpp文件,声明的目的就是告知编译器某个函 数已经在别处被定义过了(可能是别的.cpp文件中,也可以是在同一个文件中函数被调用的后面),让编译通过生成obj目标文件,然后链接程序link在 连接的时候通过对每个obj文件的接口函数逐一的扫描,将对函数的调用与函数的实现对应起来,如果在所有的obj文件中都没有找到已经声明过的函数,那么 link将报错(link error)。.h文件时不参与编译器的编译过程的,#include "…….h"宏的作用就是在对应的地方原文插入对应头文件的内容,因此头文件的存在可是使函数声明和实现分开,结构明白。
  动态链接库dll文件是代码的二进制形式,只要能够找到函数的入口地址,不用对函数进行声明就可以调(getprocaddress方式)而在利用静态链 接库.lib或者对动态链接库利用其.lib文件进行静态调用的时候,直接利用的是对应的函数名,所以需要对所调用的函数进行声明,否则编译器将不认识函 数标号而编译报错。

3.DLL与_decspec(dllexport)、_decspec(dllimport)
  DLL内的函数分为两种,DLL导出函数和DLL内部函数,其中用_decspec(dllexport)来声明DLL导出函数,声明后则此函数可以被外 部的应用程序调用,如果不加此声明的默认为DLL内部函数,只能在DLL内部使用,应用程序师无法调用它们的,在depends工具中也看不到此函数的。
  _decspec(dllimport)是在调用DLL内的函数的时候声明此函数为导入函数的(对于应用程序本身而言,调用dll的函数为导入)

  看到一段比较经典的话:DLL导出函数的链接(extern "C")、导入( _decspec(dllimport) )、和导出指示符( _decspec(dllexport) )在函数第一次声明时确定,在以后的函数声明和定义时,函数都接受第一次的函数的链接、导入、导出声明,不必再次对函数做链接、导入、导出声明。
  如果导出函数声明和定义的函数调用约定不一致(如声明为默认的_cdecl,而在定义的时候为_stdcal)在编译报错。

4.DLL和lib文件的关系
  大的来讲,dll是动态链接库,而.lib为静态链接库,应该没有什么关系才对,但某中说法来讲是的,但要注意到在生成dll的时候一般同时会生成一个同 名的lib文件,这就是为上面第2点讲述的为dll的静态调用准备的,此时声称的lib文件并不包含函数的二进制代码,其中仅仅包含着函数名称到动态链接 库dll的对应函数的入口地址这个映射而已,函数的执行代码最终还是在dll文件中。
  而静态链接的lib文件则包含着函数的执行二进制代码,每当调用该函数的时候,就在调用处拷贝一份代码链接到应用程序的.exe文件中,这增加了最终生成 的.exe文件体积,但程序发布的时候却不必发布.lib文件,而用到动态链接库dll的程序发布的时候要连所用到的dll文件一起发布。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值