`
lyunabc
  • 浏览: 530177 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

创建自己的dll与lib:dll与lib文件的区别

 
阅读更多

原文地址:http://blog.csdn.net/dizuo/article/details/4103614

经常使用到第三方库。比如:glut,freetype,sdl,大一点的有CEGUI,OSG等。

这些库虽然是开源的,但是很多时候只是使用他们,一般不会去修改。

使用就会涉及到三个东西:.h .lib .dll文件。

主要有三种模式:

.h+.lib

.h+.lib+.dll

.dll

第二种是最常见的,其他两种都比较少

一,下面自己实现一个dll和lib:

英文链接网址:http://msdn.microsoft.com/en-us/library/ms235636(VS.80).aspx

注意我的编译器是vs2005。

1,建立一个win32控制台应用程序, 输入工程名字后点击确定 点击下一步, 选择应用程序类型: DLL 附加选项选择:空项目 。点击确定

2,在空的工程中添加头文件MathFuncsDll.h ,内容如下:

  1. //MathFuncsDll.h
  2. namespaceMathFuncs
  3. {
  4. classMyMathFuncs
  5. {
  6. public:
  7. //Returnsa+b
  8. static__declspec(dllexport)doubleAdd(doublea,doubleb);
  9. //Returnsa-b
  10. static__declspec(dllexport)doubleSubtract(doublea,doubleb);
  11. //Returnsa*b
  12. static__declspec(dllexport)doubleMultiply(doublea,doubleb);
  13. //Returnsa/b
  14. //ThrowsDivideByZeroExceptionifbis0
  15. static__declspec(dllexport)doubleDivide(doublea,doubleb);
  16. };
  17. }

3,添加MathFuncsDll.cpp文件内容如下:


  1. //MathFuncsDll.cpp
  2. //compilewith:/EHsc/LD
  3. #include"MathFuncsDll.h"
  4. #include<stdexcept>
  5. usingnamespacestd;
  6. namespaceMathFuncs
  7. {
  8. doubleMyMathFuncs::Add(doublea,doubleb)
  9. {
  10. returna+b;
  11. }
  12. doubleMyMathFuncs::Subtract(doublea,doubleb)
  13. {
  14. returna-b;
  15. }
  16. doubleMyMathFuncs::Multiply(doublea,doubleb)
  17. {
  18. returna*b;
  19. }
  20. doubleMyMathFuncs::Divide(doublea,doubleb)
  21. {
  22. if(b==0)
  23. {
  24. thrownewinvalid_argument("bcannotbezero!");
  25. }
  26. returna/b;
  27. }
  28. }

4, 设置工程属性:

左边解决方案资源管理器中右击工程名:弹出的对话框中:左边,配置属性:/常规 下: 右边 配置类型:选择动态库(.dll)

然后点击生成:/ 生成 MathFuncDll。

此时可以到debug文件夹下去查看一下: MathFuncsDll.dll MathFuncsDll.lib 这两个文件是我们最关心的。注意此时的MathFuncsDll.lib文件只有3kb大

二,使用dll和lib文件

新建一个空的win32控制台应用程序:UseMathDll项目名字

添加cpp文件MyExecRefsDll.cpp:

  1. #include<iostream>
  2. #include"MathFuncsDll.h"
  3. #pragmacomment(lib,"MathFuncsDll.lib")//导入lib文件
  4. usingnamespacestd;
  5. intmain()
  6. {
  7. doublea=7.4;
  8. intb=99;
  9. cout<<"a+b="<<
  10. MathFuncs::MyMathFuncs::Add(a,b)<<endl;
  11. cout<<"a-b="<<
  12. MathFuncs::MyMathFuncs::Subtract(a,b)<<endl;
  13. cout<<"a*b="<<
  14. MathFuncs::MyMathFuncs::Multiply(a,b)<<endl;
  15. cout<<"a/b="<<
  16. MathFuncs::MyMathFuncs::Divide(a,b)<<endl;
  17. system("PAUSE");
  18. return0;
  19. }

然后将MathFuncsDll.lib 和 MathFuncsDll.h文件 放到和MyExecRefsDll.cpp一个文件目录下,也就是当前目录下。将MathFuncsDll.dll可以放到system32下,当然了最简单的做法就是放到UseMathDll这个工程的debug或者release文件夹里面,将来生成的exe就可以直接在当前目录下找到需要的dll文件。(动态链接文件,如果不把dll放入system32或者debug中,会导致程序无法运行。因为真正的函数的可执行代码都在dll中。lib文件仅仅只是一个索引,而.h文件仅仅只给出了一个借口而已。)

此时就可以点击运行了:

结果如下:


  1. a+b=106.4
  2. a-b=-91.6
  3. a*b=732.6
  4. a/b=0.0747475
  5. 请按任意键继续...

三,直接使用.h 和 lib文件

还是打开MathFuncsDll工程项目,依照条目一中的设置工程属性:不过最后的配置类型 选择静态库(.lib)

然后生成MathFuncsDll,然后到debug下面看一下,此时的MathFuncsDll.lib文件变成了29k

然后把MathFuncsDll.lib替换掉UseMathDll工程目录下的原来的MathFuncsDll.ib文件,而且把Debug下的MathFuncsDll.dll删掉,UseMathDll照样正常运行。


下面是dll与lib的详细对比:


.h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的。

附加依赖项的是.lib不是.dll,若生成了DLL,则肯定也生成 LIB文件。如果要完成源代码的编译和链接,有头文件和lib就够了。如果也使动态连接的程序运行起来,有dll就够了。在开发和调试阶段,当然最好都有。

.h .lib .dll三者的关系是:

H文件作用是:声明函数接口

DLL文件作用是: 函数可执行代码

当我们在自己的程序中引用了一个H文件里的函数,编链器怎么知道该调用哪个DLL文件呢?这就是LIB文件的作用: 告诉链接器 调用的函数在哪个DLL中,函数执行代码在DLL中的什么位置,这也就是为什么需要附加依赖项 .LIB文件,它起到桥梁的作用。如果生成静态库文件,则没有DLL ,只有lib,这时函数可执行代码部分也在lib文件中

目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。比如你链接一个静态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则你可能就需要自己LoadLibary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

一般的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。在动态库的情况下,有两个文件,而一个是引入库(.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。

-------------------------------------------------------------------------------------

静态链接库(Lib)与动态链接库(DLL)的区别

<wbr><wbr><wbr> 静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序运行的时候不再需要其它的库文件;动态链接就是把调用的函数所在文件模块(DLL)和调用函数在文件中的位置等信息链接进目标程序,程序运行的时候再从DLL中寻找相应函数代码,因此需要相应DLL文件的支持。<wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr>静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。</wbr></wbr></wbr>


<wbr><wbr>“每一个lib文件就是若干函数(假设只有函数)的定义”<wbr><br><wbr><wbr><wbr>lib库有两种,一种是包含了函数所在DLL文件和文件中函数位置的信息,称为导出库;一种是包含函数代码本身,一般现有的DLL,用的是前一种库;以前在DOS下的TC/BC等,是后一种库。包含函数原型声明的,是头文件(.h)。<wbr><br><wbr><wbr><br><wbr><wbr><wbr>“通过#include包含这些函数声明的头文件后,我们的应用程序就可以使用lib文件中的函数”<wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr>还要指定编译器链接相应的库文件。在IDE环境下,一般是一次指定所有用到的库文件,编译器自己寻找每个模块需要的库;在命令行编译环境下,需要指定每个模块调用的库。<wbr><br><wbr><wbr><br><wbr><wbr>“那他和直接给出那个函数定义的文件,比如.cpp文件,和头文件有什么区别,静态链接库有什么用”<wbr><br><wbr><wbr><wbr>cpp文件是源代码,库文件是编译后的二进制代码,比如你可以调用Windows的API,但是不能看到其源代码一样。<wbr><br><wbr><wbr><br><wbr><wbr>“还有不明白的是,静态链接库中的lib文件只要用到,则整个lib文件的内容都放进了exe文件中,那它是被编译进去还是链接的时候连接进去的呢?”<wbr><wbr><wbr><br><wbr><wbr><wbr>是在链接的时候将lib链接到目标代码中。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

静态链接库(Lib)
在VC++6.0中new一个名称为libTest的static library工程,

并新建lib.h和lib.cpp两个文件,lib.h和lib.cpp的源代码如下:

//文件:lib.h
#ifndef LIB_H
#define LIB_H
extern "C" int add(int x,int y);   //声明为C编译、连接方式的外部函数
#endif

//文件:lib.cpp
#include "lib.h"
int add(int x,int y)
{
return x + y;
}


  编译这个工程就得到了一个.lib文件,这个文件就是一个函数库,它提供了add的功能。将头文件和.lib文件提交给用户后,用户就可以直接使用其中的add函数了。

  标准Turbo C2.0中的C库函数(我们用来的scanf、printf、memcpy、strcpy等)就来自这种静态库。

<wbr><wbr><wbr>下面来看看怎么使用这个库,在libTest工程所在的工作区内new一个libCall工程。libCall工程仅包含一个main.cpp文件,它演示了静态链接库的调用方法,其源代码如下:</wbr></wbr></wbr>

#include <stdio.h>
#include "..\lib.h"//不可丢失
#pragma comment( lib, "..\\debug\\libTest.lib" )  //指定与静态库一起连接
int main(int argc, char* argv[])
{
<wbr><wbr><wbr> printf( "2 + 3 = %d", add( 2, 3 ) );<br> }<br>   静态链接库的调用就是这么简单,或许我们每天都在用,可是我们没有明白这个概念。代码中#pragma comment( lib , "..\\debug\\libTest.lib" )的意思是指本文件生成的.obj文件应与libTest.lib一起连接</wbr></wbr></wbr>



分享到:
评论

相关推荐

    dll文件转换为lib

    使用pexport和lib工具将dll转换为lib。

    opencv2.0中的lib和dll,跑别人程序时可能会用到,到处找后整理起来的

    这里把所有的文件名列出来,有需要的就下吧: 2.0:lib:cv200.lib; cv200d.lib; cvaux200.lib; cvaux200d.lib; cxcore200.lib; cxcore200d.lib; cxts200.lib; cxts200d.lib; highgui200.lib; highguid.lib; ml...

    gdal和geos联合编译后dll和lib文件

    gdal和geos联合编译后dll和lib文件。gdal如果不与geos一起联合编译,gdal功能中的一些空间分析功能将无法使用,联合编译是一件很费劲的事情,资源中是已经联合编译好的库文件。

    通过DLL生成LIB

    最近遇到需要修改LIB名称的事,想着重新编译LIB需要编译大半天实在太耗时间了,所以自己写了个软件,只需要将DLL改个名字重新生成LIB即可,已通过测试,仅支持支持VS C/C++平台的动态链接库,自动识别X86还是X64平台...

    生成DLL和lib文件测试案例

    VS2015生成dll文件和lib文件,里面含有测试生成的lib文件和dll文件。具体怎么配置,请参考案例

    dll和lib的区别

    dll和lib的区别

    H LIB DLL文件的区别月联系

    H LIB DLL文件的区别月联系H LIB DLL文件的区别月联系H LIB DLL文件的区别月联系

    dll to lib 3.00 本人汉化版

    dll to lib 3.00 本人在破解版的基础上汉化 未汉化二进制里的字符串,使用ok

    OpenGL所有头文件 dll和lib文件

    opengl开发的头文件,lib文件和拓展库文件dll

    由DLL文件生成LIB文件的工具

    选择DLL文件,自动生成DEF文件和LIB文件

    dll2lib.rar (需要安装 python2.X )

    压缩包中除上述网址的dll2lib.py外还含有 VC 6 的如下几个文件: DUMPBIN.EXE LIB.EXE LINK.EXE MSPDB60.DLL 该python脚本对一个 A.dll 文件会生成如下三个文件: A.lib A.def A.exp 因为是 python 写的,所以需要...

    OpenCV-4.7.0 lib 与 dll 文件

    用 VS2015 由 OpenCV 4.7.0 源码编译生成的 lib 和 dll 文件, 包含了 None free 模块, Opencv_Contrib-4.7.0. 不包含 Cuda

    Dll2Lib 3.0

    Dll2Lib 3.0 Welcome to DLL to Lib. DLL to Lib is a magical tool which can convert a DLL file into its equivalent static library file so that you can distribute your applications without the DLLs.

    DLL导出生成lib文件

    对于没有lib文件的DLL,在VC中需要引用,怎么操作呢。这个工具就是实现该功能的,附带一个命令使用例子。

    sqlite在VC6下面的DLL与LIB文件

    sqlite3在vc6下面使用的dll与lib文件,已经完全验证过,请放心使用

    DLL转Lib工具

    DLL2Lib,编程高手必备工具,值得拥有。

    dll导出lib工具

    C99没法在VC下直接编译,利用mingw+msys先生成dll,然后dll导出lib 如果不会用,请看http://blog.sina.com.cn/u/1964716381

    tesseract_dll_lib_vs2008编译好的dll库和lib文件

    tesseract_dll_lib_vs2008编译好的dll库和lib文件,包含以下文件:libtesseract302-static-debug.lib libtesseract302-static.lib libtesseract302.dll libtesseract302.exp libtesseract302.lib libtesseract302d....

    dll2lib:用于从“.dll”文件生成“.lib”文件的便捷实用程序

    DLL2库Dll2Lib 是一个方便的实用程序,用于从“.dll”文件生成“.lib”文件。 它提供了一个简单的 GUI 来调用适当的 Visual Studio 命令行工具。 在尝试使用此实用程序之前,请确保您的系统上安装了 Visual Studio。

    DLL2LIB.zip

    DLL生成LIB的工具箱。里面包含两个工具,一个工具快速生成DEF和LIB文件,另一个工具修改LIB文件的函数命名方式。

Global site tag (gtag.js) - Google Analytics