C/C++::浅谈.obj .exe .dll .lib关系&& .o .a .so关系

浅谈.lib .dll .obj 关系&& .a .so .o关系 


一、.obj .exe .dll .lib

(1).obj

  • 目标文件,相当于源代码对应的二进制文件。
  • obj文件就是用.c .cpp .h文件经过编译器编译之后生成的目标文件。

(2).exe

  • 将程序运行所需要的全部.obj文件连接起来,即形成.exe文件。
  • 也就是windows下的可执行文件。
  • obj只给出了程序的相对地址,而EXE是绝对地址

(3).dll

  •  .dll是可提供给多个程序同时使用的可执行代码和数据(资源 )的库
  • 可简单理解为封装好的.cpp,里面装的是函数的具体实现
  • .dll是动态编译出来的程序运行时所需要的库,没有.dll文件,动态编译的程序就不能运行

(4).lib

  • .lib是编译程序时所需的,非运行时所需
  • .lib分为静态和动态
  • 静态.lib包括了方法及其具体实现。
  • 动态.lib只有方法的声明,简单来看相当于一个h文件,是对实现部分(.dll文件)的导出部分的声明。作用是告诉链接器具体用到了哪个dll文件,以及定位到dll文件内部的函数具体实现位置。
  • 利用静态lib编译出来的程序,运行时不需要.dll文件的支持。
  • 利用动态lib编译出来的程序,运行时需要.dll文件提供方法的具体实现
  • 实际上:.lib文件可看做是若干个.obj文件的集合

(5)一个C/C++工程需要用到其他.c .h .cpp类库、函数库时,其包含的方式有如下图的几种方式

  • 1、最直接的方式就是将该类库的.h .cpp 直接引入到工程中,直接完全编译
  • 2、另外的方法是先将该类库生成为一个静态的lib库,引入工程时只需包含.h以及.lib文件,编译时将所需的方法具体实现从.lib中提取到可执行文件,可执行文件可不需要其他东西的支持就可直接运行
  • 3、常用的方法是将该类库生成一个动态的lib库,还有与之对应的.dll文件,引入工程时也只需包含.h以及.lib文件,但这个动态的.lib文件仅仅提供方法的声明,具体的实现被打包在.dll文件中,因此运行生成的可执行文件需要.dll文件的支持

实战:

1)动态库的生成(lib和dll)

a、新建项目,win32,win32项目,输入项目名称,例如makedll2

b、选择dll、导出符号

c、自动生成makedll2.h

  • #define MAKEDLL2_API __declspec(dllexport)表明这些东西可以被外部函数使用,即(dllexport)是把DLL中的相关代码(类,函数,数据)暴露出来为其他应用程 序使用
  • class MAKEDLL2_API Cmakedll2  表示导出类,这个类为Cmakedll2类
  • extern MAKEDLL2_API int nmakedll2;  声明导出变量
  • MAKEDLL2_API int fnmakedll2(void);  声明导出函数
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 MAKEDLL2_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// MAKEDLL2_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef MAKEDLL2_EXPORTS
#define MAKEDLL2_API __declspec(dllexport)
#else
#define MAKEDLL2_API __declspec(dllimport)
#endif

// 此类是从 makedll2.dll 导出的   类名为Cmakedll2
class MAKEDLL2_API Cmakedll2 {
public:
	Cmakedll2(void);
	// TODO:  在此添加您的方法。
};

//声明导出变量
extern MAKEDLL2_API int nmakedll2;

//声明导出函数
MAKEDLL2_API int fnmakedll2(void);

d、makedll2.cpp

  • 导出内容的具体实现
// makedll2.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "makedll2.h"


// 这是导出变量的一个示例
MAKEDLL2_API int nmakedll2=0;

// 这是导出函数的一个示例。
MAKEDLL2_API int fnmakedll2(void)
{
	return 42;
}

// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 makedll2.h
Cmakedll2::Cmakedll2()
{
	return;
}

 e、构建

f、检查生成的.dll和.lib

 2)动态库的使用

方式一、vs2013下进行项目配置

a、新建一个win32控制台项目

b、在属性管理器中,双击debug或者release

将包含目录设置为刚刚生成dll项目的头文件.h所在文件夹

将库目录设置为刚刚生成dll项目的debug文件夹,也就是.lib所在的文件夹

c、在链接器--->输入页面中,在附加依赖项中添加刚刚生成的.lib文件

c、新建main.cpp文件,对刚刚封装的库进行调用

#include<iostream>
using namespace std;
#include"makedll2.h"

int main()
{
	Cmakedll2 testdll; //这个是刚刚封装成lib里面的导出类
	//输出导出变量
	cout <<"这个是导出变量:"<< nmakedll2 << endl;
	//调用的导出函数
	cout << "调用导出函数输出:" << fnmakedll2() << endl;
	system("pause");
	return 0;
}

 d、点击运行,应该会报错如下:

e、将上面生成的库.dll文件复制到这个项目的debug下

f、运行,得到如下结果:

 方式二、直接在项目中添加lib文件【适用于lib文件较少的情况】

a)新建完项目后,项目视图中右键,添加,现有项,选择所生成的lib文件即可

b)库的.h头文件放在项目目录下

c)库的.dll文件放在项目的debug目录下

方式三、 直接在源文件中加入代码

#pragma comment(lib, "makedll2.lib")

这里引用https://www.cnblogs.com/qinguoyi/p/7257353.html的总结,

动态库使用方法总结

  .h,.lib,.dll的添加方法其实各有很多种。

.h有两种:

  1. 头文件较少时,直接放在工程目录下,#include "*.h"

  2. 建立include文件夹,放在里面,然后在项目属性的“VC++目录”-》“包含目录”,添加.h路径即可。

.lib的方法有两种

  1.lib文件较少时,直接放在工程目录下,#pragma comment(lib, "testCpp.lib")

  2.建立lib文件夹,目属“VC++目录”-》“库目录”添加路径,然后在项目属性的“链接器”-》“输入”-》“附加依赖项”,添加.lib名字。

dll的方法有两种

  1.直接放在debug/release目录下

  2.建立bin文件夹,放在里面,然后在项目“环境”中添加bin的路径(PS:最好不要用这个)

 3)静态库的生成和使用可参考动态库,使用时不再需要将.dll文件复制到exe目录,因为静态编译将exe所需的内容都提取到exe里面了。

 



 二、.a .so .o

(1).o

  • 目标文件,相当于windows下的.obj
  • 是编译得到的结果,即源码编译后得到的二进制文件

(2).a 

  • 静态库文件
  • 相当于windows下的静态.lib
  • 相当于一个或多个.o文件的集合,可直接由.o文件生成
  • .a的命名格式:lib+函数库名+.a
  • 构建.a静态库方法:使用ar工具
  • 使用.a静态库方法:gcc生成可执行文件时,使用-l(小写)参数指定要加入的库函数。也可以用ld命令的-l和-L参数
  • 使用举例:gcc -o hello main.c -L. –l库名     #-L 后面指定静态库路径   -l不用空格后直接加静态库名(lib后面的东西)

(3).so

  • 动态库文件,一般叫共享库,share
  • 相当于windows下的.dll
  • .so的命名格式:lib+函数库名+.so+版本号信息(但是记住,非常底层的C库函数都不是以lib开头命名的)
  • 构建.so动态库方法:gcc -fPIC -shared -o lib库名.so.1 atoi.c
  • 使用.so动态库方法:gcc -o main main.o -Wl,-rpath=. lib库名.so.1     #-Wl,-rpath:指定库所在路径
  • 查看可执行文件所依赖的动态库情况:ldd  可执行文件

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值