解析dll文件和lib文件的区别

news/2024/6/29 11:55:23 标签: dll, application, 编译器, winapi, library, c
cle class="baidu_pl">
cle_content" class="article_content clearfix">
content_views" class="htmledit_views">
class="tit"> 摘自: http://hi.baidu.com/sihochina/blog/item/8c8b570611452f7e0308813d.html
class="tit"> 解析class="tags" href="/tags/DLL.html" title=dll>dll文件和lib文件的区别(如何利用VC创建DLL文件)
class="date"> 2008年04月23日 星期三 下午 01:47
class="cnt">

    .class="tags" href="/tags/DLL.html" title=dll>dll是在你的程序运行的时候才连接的文件࿰c;因此它是一种比较小的可执行文件格式࿰c;.class="tags" href="/tags/DLL.html" title=dll>dll还有其他的文件格式如.ocx等࿰c;所有的.class="tags" href="/tags/DLL.html" title=dll>dll文件都是可执行。

    .lib是在你的程序编译连接的时候就连接的文件࿰c;因此你必须告知class="tags" href="/tags/BianYiQi.html" title=编译器>编译器连接的lib文件在那里。一般来说࿰c;与color: #ff6600;">动态连接文件相对比࿰c;lib文件也被称为是color: #ff6600;">静态连接库。当你把代码编译成这几种格式的文件时࿰c;在以后他们就不可能再被更改。如果你想使用lib文件࿰c;就必须:
color: #3366ff;">1. 包含一个对应的头文件告知class="tags" href="/tags/BianYiQi.html" title=编译器>编译器lib文件里面的具体内容
2 .设置lib文件允许class="tags" href="/tags/BianYiQi.html" title=编译器>编译器去查找已经编译好的二进制代码

    如果你想从你的代码分离一个class="tags" href="/tags/DLL.html" title=dll>dll文件出来代替静态连接库࿰c;仍然需要一个lib文件。这个lib文件将被连接到程序告诉操作系统在运行的时候你想用到什么 class="tags" href="/tags/DLL.html" title=dll>dll文件࿰c;一般情况下࿰c;lib文件里有相应的class="tags" href="/tags/DLL.html" title=dll>dll文件的名字和一个指明class="tags" href="/tags/DLL.html" title=dll>dll输出函数入口的顺序表。如果不想用lib文件或者是没有lib文件࿰c;可以使用WIN32 API函数LoadLibrary、GetProcAddress。事实上࿰c;我们可以在Visual C++ IDE中以二进制形式打开lib文件࿰c;大多情况下会看到ASCII码格式的C++函数或一些重载操作的函数名字。

     一般我们最主要的关于lib文件的麻烦就是出现color: #ff6600;">unresolved symble 这类错误࿰c;这就是color: #ff6600;">lib文件连接错误或者没有包含.c、.cpp文件到工程里c;关键是如果在C++工程里用了C语言写的lib文件࿰c;就必需要这样包含:
color: #3366ff;">extern "C"
{
#include "myheader.h"
}

这是因为C语言写的lib文件没有C++所必须的名字破坏࿰c;C函数不能被重载࿰c;因此连接器会出错。

===============================

在VC中不用MFC如何制作class="tags" href="/tags/DLL.html" title=dll>dll

方法一:使用export 和 import

在VC中建立一个Console Application࿰c;建立2个文件:Dll.h 和 Dll.cpp

Dll.h
color: #3366ff;">========================================================
#ifdef MYLIBAPI
#else
#define MYLIBAPI extern "C" _declspec (class="tags" href="/tags/DLL.html" title=dll>dllimport)
#end if

color: #3366ff;">MYLIBAPI int Add (int iLeft, int iRight)
MYLIBAPI int Sub (int iLeft, int iRight)
========================================================

Dll.cpp
color: #3366ff;">========================================================
#define MYLIBAPI extern "C" _declspec (class="tags" href="/tags/DLL.html" title=dll>dllexport)

color: #3366ff;">#include "Dll.h"

color: #3366ff;">int Add (int iLeft, int iRight)
{
return iLeft + iRight ;
}

color: #3366ff;">int Sub (int iLeft, int iRight)
{
return iLeft - iRight ;
}
========================================================

保存文件。在color: #ff6600;">Project->setting->link 最下面加上 “/class="tags" href="/tags/DLL.html" title=dll>dll”࿰c; "/"之前一定要与前一项有空格。然后编译࿰c;就可以在debug 或 release下面找到class="tags" href="/tags/DLL.html" title=dll>dll 和 lib 文件了使用的时候包含class="tags" href="/tags/DLL.html" title=dll>dll.h文件。

方法二:使用def文件
建立一个console class="tags" href="/tags/APPLICATION.html" title=application>application, 建立2个文件class="tags" href="/tags/DLL.html" title=dll>dll.h 和 class="tags" href="/tags/DLL.html" title=dll>dll.cpp

Dll.h
color: #3366ff;">========================================================
int Add (int iLeft, int iRight) ;
int Sub (int iLeft, int iRight) ;
========================================================

Dll.cpp
color: #3366ff;">========================================================
#include "Dll.h"

color: #3366ff;">int Add (int iLeft, int iRight)
{
return iLeft + iRight ;
}

color: #3366ff;">int Sub (int iLeft, int iRight)
{
return iLeft - iRight ;
}
========================================================

然后再当前目录下面建立一个.def文件࿰c;文件名最好和要输出的class="tags" href="/tags/DLL.html" title=dll>dll名字一样࿰c;扩展名为.def, 里面写上:

color: #3366ff;">LIBRARY class="tags" href="/tags/DLL.html" title=dll>dllname.class="tags" href="/tags/DLL.html" title=dll>dll
EXPORTS
Add @1
Add @2

然后将这个文件添加到工程中࿰c;在link中设置 /class="tags" href="/tags/DLL.html" title=dll>dll࿰c; 然后编译在debug或release中就可以找到class="tags" href="/tags/DLL.html" title=dll>dll和lib了
使用的时候加上class="tags" href="/tags/DLL.html" title=dll>dll.h文件。

再补充一点:
    class="tags" href="/tags/DLL.html" title=dll>dll是个编译好的程序࿰c;调用时可以直接调用其中的函数࿰c;不参加工程的编译。而lib应该说是一个程序集࿰c;只是把一些相应的函数总结在一起࿰c;如果调用lib中的函数࿰c;在工程编译时,这些调用的函数都将参加编译。

    简单讲࿰c;静态库就是直接将需要的代码连接进可执行程序;动态库就是在需要调用其中的函数时࿰c;根据函数映射表找到该函数然后调入堆栈执行。
color: #ff6600;">做成静态库可执行文件本身比较大࿰c;但不必附带动态库
做成动态库可执行文件本身比较小࿰c;但需要附带动态库
其它没有什么对于程序员而言很大的区别࿰c;有的Unix可能不支持动态库࿰c;所以只好用静态库。

DLL与LIB的区别:
1.DLL是一个完整程序࿰c;其已经经过链接࿰c;即不存在同名引用࿰c;且有导出表࿰c;与导入表lib是一个代码集(也叫函数集)他没有链接࿰c;所以lib有冗余࿰c;当两个lib相链接时地址会重新建立࿰c;当然还有其它相关的不同࿰c;用lib.exe就知道了;
2.在生成class="tags" href="/tags/DLL.html" title=dll>dll时࿰c;经常会生成一个.lib(导入与导出)࿰c;这个lib实际上不是真正的函数集࿰c;其每一个导出导入函数都是跳转指令࿰c;直接跳转到DLL中的位置࿰c;这个目的是外面的程序调用class="tags" href="/tags/DLL.html" title=dll>dll时自动跳转;
3.实际上最常用的lib是由lib.exe把*.obj生成的lib。

 

摘自csdn论坛:
调用DLL有两种方法:静态调用和动态调用.
(一).静态调用其步骤如下:
1.把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下;
2.把你的youApp.lib拷到你目标工程(需调用youApp.DLL的工程)目录下;
3.把你的youApp.h(包含输出函数的定义)拷到你目标工程(需调用youApp.DLL的工程)目
录下;
4.打开你的目标工程选中工程,选择Visual   C++的Project主菜单的Settings菜单;
5.执行第4步后࿰c;VC将会弹出一个对话框࿰c;在对话框的多页显示控件中选择Link页。然
后在Object/class="tags" href="/tags/LIBRARY.html" title=library>library   modules输入框中输入:youApp.lib
6.选择你的目标工程Head   Files加入:youApp.h文件;
7.最后在你目标工程(*.cpp,需要调用DLL中的函数)中包含你的:#include   "youApp.h "
注:youApp是你DLL的工程名。
2.动态调用其程序如下:
动态调用时只需做静态调用步骤1.
{
HINSTANCE   hDllInst   =   LoadLibrary( "youApp.DLL ");
if(hDllInst)
{
typedef   DWORD   (WINAPI   *MYFUNC)(DWORD,DWORD);
MYFUNC   youFuntionNameAlias   =   NULL;   //   youFuntionNameAlias   函数别名
youFuntionNameAlias   =   (MYFUNC)GetProcAddress
(hDllInst, "youFuntionName ");
//   youFuntionName   在DLL中声明的函数名
if(youFuntionNameAlias)
{
youFuntionNameAlias(param1,param2);
}
FreeLibrary(hDllInst);
}
}

cle>

http://www.niftyadmin.cn/n/739363.html

相关文章

回调函数实现类层次结构上下层的通信

首先用摘自VCKBase上的一篇文章介绍下函数指针和回调函数。 程序员常常需要实现回调。本文将讨论函数指针的基本原则并说明如何使用函数指针实现回调。注意这里针对的是普通的函数,不包括完全依赖于不同语法和语义规则的类成员函数(类成员指针将在另文中…

驾校科目三考试项目

1. 上车前准备 上车前前后查看、验证指纹、前后查看后开车门上车后调整座椅、安全带、空档点火、灯光模拟前后、左右观察后 开左转向灯一档起步松手刹、送离合器、稳定、 送刹车 2. 灯光 3. 超车、变道 开左转向灯、变换灯光、多次查看左后方车辆、前方车辆情况、加速、加档…

深入浅出MFC读书笔记1

第二次读《深入浅出MFC》比第一次轻松多了。这里记录一下,我自认为的重点的内容,包括一些经常疑惑的细节。 Win32中CALLBACK被定义为_stdcall,是一种函数调用习惯,关系到参数进入到堆栈的次序,以及处理堆栈的责任归属,其它的函数…

PHP使用Redis存储session时的一个Warning定位

1. 问题现象 系统页面刷新的时候,偶尔会报错下面的Warnning,但是不经常出现: Warning: Unknown: Failed to write session data (redis). Please verify that the current setting of session.save_path is correct (tcp://x.x.x.x:6379?authyyy) in …

MATALB中信号的阈值去噪

摘自http://blog.chinaaet.com/detail/3083.html MATLAB中实现了信号的阈值去噪,主要包括阈值去噪和阈值获取两方面。 1.阈值获取MATLAB中实现阈值获取的函数有ddencmp、thselect、wbmpen和wwdcbm,下面对它们的用法进行简单的说明。 ddencmp的调用格式…

HTTP POST提交数据方式不同引起的躺坑记

HTTP POST提交数据方式不同引起的躺坑记 jasonye 2017-08-12 问题现象: PHP代码中调用curl POST提交的数据,在Go Server端一直用PostFormValue读不到,但是用curl -d命令提交的数据可以读取到。 定位问题: 在试图采用postman…

Effecitve C++读书笔记(一)

最近工作中开始又使用C了,而且应用软件的开发C语言确实有了一定的局限。所以还是准备多看一些关于C的书籍,总结下。 视C为一个语言联盟,我个人觉得这是一个绝妙的想法。因为C和C的纠葛不清,但是又因为是一门高级的面向对象的语言…

go语言包管理

包名字可以和目录名字 可以不一样, 但是推荐一样,便于快速查找识别到包,否则容易误解一个目录中只包含一个包、包含多个包会报错一个包可以放在多个文件中、包文件只放在src文件目录下,通过GOPATH引用、否则引用不到。import只要引…