lib库dll库的使用方法与关系
一、lib库
lib库有两种:一种是静态lib(static Lib),也就是最常见的lib库,在编译时直接将代码加入程序当中。静态lib中,一个lib文件实际上是任意个obj文件的集合,obj文件是cpp文件编译生成的。
另一种lib包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供。也就是平时编写dll时附带产生的lib,其中Lib只是Dll的附带品,是DLL导出的函数列表文件而已。
共同点:两者都是二进制文件,都是在链接时调用,使用static lib的exe可以直接运行,使用另一种lib的exe需要对应的dll才能运行。
静态lib库的创建示例:
1.VS2005(包含)以上的版本
2.建立win32控制台工程
3.下一步选择static library
4.完成
代码:
//mylib.h
#ifndef MYLIB_H_H
#define MYLIB_H_H
#include "stdafx.h" void display();
void display1();
void display2(); #define A(x) (x)*(x) #endif
//mylib.cpp
#include "stdafx.h"
#include "mylib.h" void display()
{
cout<<"This is display"<<endl;
} void display1()
{
cout<<"This is display1"<<endl;
} void display2()
{
cout<<"This is display2"<<endl;
}
编译之后生成一个mylib.lib的库文件,引用库文件如下:
右击工程-->属性(alt+F7)-->C/C++-->附加包含目录--->包含所需要的头文件。
右击工程-->属性(alt+F7)-->链接器-->常规--->附加目录--->包含lib库所在的目录
右击工程-->属性(alt+F7)-->输入--->附加依赖项--->lib库名
这样就能引用该lib内的函数了
#include "stdafx.h"
#include "mylib.h" int _tmain(int argc, _TCHAR* argv[])
{
display();
display1();
display2();
cout<<A(-)<<endl;
getchar();
return ;
}
当然,还可以使用#pragma comment(lib, "LibPath")的方法来调用Lib文件,同时必须包含相应的头文件。
另一种lib库的使用方法:用法静态库一致,唯一不同的区别是运行时要加上相应的dll。
DLL的用法:
dll其实和exe是几乎完全一样的,唯一的不一样就是Exe的入口函数式WinMain函数(控制台程序是main函数),而Dll是DllMain函数,其他完全是一样的。所以有人也戏称dll是不能自己运行的exe。dll的创建也比较简单唯一麻烦的就是要定义导出函数接口。
dll的创建过程:
建立win32控制台工程,在应用程序设置的步骤,选择”动态库 Dynamic Library”,完成即可。(这里只是针对最简单的Dll,Win32 Application的方式稍有不同)
定义导出函数接口的方法有两种:
1.使用__declspce宏
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h" BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
//mydll1.h #ifndef MYDLL_H_H
#define MYDLL_H_H extern "C" __declspec(dllexport) void display(void);
extern "C" __declspec(dllexport) void display1(void);
void display2(void); #endif
//mydll1.cpp
#include "stdafx.h"
#include "mydll1.h" void display(void)
{
cout<<"call display()"<<endl;
} void display1(void)
{
cout<<"call display1()"<<endl;
} void display2(void)
{
cout<<"call display2()"<<endl;
}
mydll1.h头文件中的:
extern "C" __declspec(dllexport) void display(void);
这里的extern "C" 表示我们要按照C语言的方式编译该函数,防止在C++工程中编译出现函数名错误,因为C中没有重载而C++中允许重载,所以C++中函数编译后会出现display@1的形式;让编译器以C语言的编译方式编译可以保证C可以调用C++的动态链接库。__declspec(dllexport)表示下来的函数是dll的导出函数接口。没有导出的接口是不可使用的,这里和静态lib库有所区别,静态lib库中的所有函数、宏定义等都是可以使用的。
2.使用def文件,该文件的功能类似于__declspec(dllexport)的功能。
在资源文件目下添加def文件:
LIBRARY
EXPORTS
display
display1
dll的调用:
1.dll的显示调用:前提是我们必须知道函数名、返回值、参数列表。此时不需要相应的头文件,也不需要lib文件。只需要对应的dll就可以了。
// test_my_dll.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include "windows.h" int _tmain(int argc, _TCHAR* argv[])
{
HINSTANCE hInstance = LoadLibrary("mydll1.dll");
typedef void(*_print)(void);
_print printFun;
if(hInstance != NULL)
{
printFun = (_print)GetProcAddress(hInstance,"display1");
}
printFun();
FreeLibrary(hInstance);
system("pause");
return ;
}
这种情况下:HINSTANCE hInstance = LoadLibrary("mydll1.dll");会出现”2 IntelliSense: "const char *" 类型的实参与 "LPCWSTR" 类型的形参不兼容 “问题。解决办法:工程--->属性--->常规-->字符集--->使用多字节字符集就可以了。
2.dll的隐式调用
这是相应的lib库就派上用场了,其用法static library用法一致。
总结:显示调用和隐式调用这两种方法各有千秋,显示调用优点是只要接口参数列表没有发生改变,修改了函数实现的细节也没关系,所调用的exe程序不用重新编译只需替换新版的dll就可以。在大的项目中只用比较方便,但调用过程相对复杂需要使用一系列的windows函数还有函数指针等。对于隐式调用和static library用法一致比较容易理解,缺点是只要修改了任意内容相应的exe都需要重新编译。
参考资料:
http://www.cppfans.org/1394.html
http://blog.csdn.net/qq419036154/article/details/6438539
http://blog.csdn.net/tianhen791/article/details/7209740
lib库dll库的使用方法与关系的更多相关文章
- 动态链接库dll,导入库lib,静态链接库lib
目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库” ...
- VC中加载LIB库文件的三种方法
VC中加载LIB库文件的三种方法 在VC中加载LIB文件的三种方法如下: 方法1:LIB文件直接加入到工程文件列表中 在VC中打开File View一页,选中工程名,单击鼠标右键,然后选中&quo ...
- 目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。静态库是一个或者多个obj文件的打包
前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”) ...
- 在VS工程中,添加c/c++工程中外部头文件(.h),lib库,dll库的基本步骤
选择工程,右键-工程属性 其中: VC++目录 -->包含目录,对所有的项目及未来新建的项目都有效 c/c++-->常规-->附加包含目录,仅对当前项目有效 绝对路径设置方法: 在V ...
- lib静态链接库,dll动态链接库,h文件
最近在弄摄像头,发现我在调用摄像头自带的函数的时候,库没连接上,于是经过高人指点,学习了一下lib静态链接库,dll动态链接库来补充一下自己的基础知识. 一.首先我们来介绍一下lib静态链接库. li ...
- Visual Studio 项目中添加include, lib, dll库文件(*.h,*.lib,*.dll)
应用程序使用外部库时需要进行加载,两种库的加载本质上都是一样:提供功能和功能的定义.vs2005 c++ 项目设置外部库方法如下: 1. 添加编译所需要(依赖)的 lib 文件 在“项目-&g ...
- 【摘自网络】dll库和lib库有什么区别
简单地讲:第一:.DLL是动态链接库,而.LIB是静态链接库dll是个编译好的程序,调用时可以直接调用其中的函数,不参加工程的编译. 而lib应该说是一个程序集, 只是把一些相应的函数总结在一起, 如 ...
- DLL、lib等链接库文件的使用
由于遇见过多次动态链接库的使用,自己也写过DLL,每次都要费好大劲去配置,现在就简单的总结一下,争取以后少走弯路! 一般都会有三个文件: .h 头文件 .lib 静态链接库 .dll 动态链接库 ...
- Python 调用 C# dll库最简方法
1.为什么要跨平台编程?双平台编程或多平台编程,只是为提供更好开发更兼容的解决方案的一种手段,编程时服务于产品和客户的,也是因地制宜. 先安装python所需的库clr ,我这里已经安装了,可以去对应 ...
随机推荐
- Merge k Sorted Lists
1. Merge Two Sorted Lists 我们先来看这个 问题: Merge two sorted linked lists and return it as a new list. The ...
- SpringMVC注入Spring的bean
一.Spring和SpringMVC两个IOC容器有什么关系呢? Spring的IOC容器包含了SpringMVC的IOC,即SpringMVC配置的bean可以调用Spring配置好的bean,反之 ...
- 第8章 Java类的三大特性之一:封装
1.什么是封装 1.1概念 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问.主要是类的属性 1.2好处 a.只能通过规定的方法访问数据b.隐藏类 ...
- python3循环语句while
Python的循环语句有for和while语句,这里讲while语句. Python中while语句的一般形式: while 条件判断 : 语句 需要注意冒号和缩进.另外,注意Python中没有do. ...
- jetty 9 嵌入式开发示例
jetty 9 嵌入应用程序后,小型的web应用直接打成一个单独的jar包,就可以直接运行,非常适合做Demo演示或云端集群部署. 主要代码: JettyServer的封装类 package yjmy ...
- 【笔记5】用pandas实现矩阵数据格式的推荐算法 (基于物品的协同)
''' 基于物品的协同推荐 矩阵数据 说明: 1.修正的余弦相似度是一种基于模型的协同过滤算法.我们前面提过,这种算法的优势之 一是扩展性好,对于大数据量而言,运算速度快.占用内存少. 2.用户的评价 ...
- Android SDK 墙内更新方法 速度杠杠的
- myeclipse 2014 除了 默认加载的derby
myeclipse 2014 去掉 默认加载的derby作为有轻微强迫症的我来说,server下面有一个我始终用不到的东西我是很不舒服的.最终我网查到解决办法,现在分享给大家.============ ...
- java画图之曲线拖动
目标:在窗体上按下鼠标按键.然后拖动鼠标,在按下和拖动之间绘制曲线 事件机制 事件源对象:窗体 事件监听方法:addMouseListener(MouseListener l);addMouseMot ...
- 如何让tableViewCell的分割线从边框顶端开始
在ios8上 [TableView setSeparatorInset:UIEdgeInsetsMake(0,0,0,0)];不起作用 经过测试加入下面方法 在ios7 8上都可以正常工作 -(voi ...