“.dll .obj .lib .exe”和“ .so .o .a .bin”文件与动态链接和静态链接

一、“.obj .exe .dll .lib ”和“.bin .so .o .a ”

1.1 “.obj .exe .dll .lib”

这几个文件是在windows下使用的文件:

(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文件的集合

1.2 “.o .bin .so .a ”

这几个文件是在Linux下使用的:

(1).o

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

(2) .bin

  • linux下的可执行文件,相当于windows下的.exe文件。

(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 可执行文件

(4).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后面的东西)
二、生成动态静态库

使用JetBrains CLion 2019.1.4

1.1 生成动态库
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.1 生成静态库

其他步骤都一样,修改CMakeLists.txt文件即可
在这里插入图片描述

二、使用动态链接库和静态链接库

1.1 使用静态库

1)方式一配置 CMakeLists.txt

cmake_minimum_required(VERSION 3.12)
project(meglev C)
set(CMAKE_C_STANDARD 99)


set(INC_DIR include) # 设置表示头文件目录的变量
set(LINK_DIR include) # 设置表示库目录的变量(库放在这里)

include_directories(${INC_DIR})     # 头文件目录
link_directories(${LINK_DIR})       # 库目录
link_libraries(libtest.lib)           # 需要链接的库(或target_link_libraries(meglev libtest.a))

add_executable(meglev main.c)

# 与link_libraries(libtest.a) 调用二选一
#target_link_libraries(meglev libtest.lib)
#include <iostream>
#include "include/lib.h"

int main() {
    get();
    return 0;
}

2)方式二

直接在代码里调用

#include <iostream>
#include "include/lib.h"

#pragma comment(lib, "D:\\pwc\\sdp\\cmake-build-debug\\sdp.lib")

extern void get();

int main() {
    get();
    std::cout << "Hello, World!" << std::endl;
    std::cout << "Hello, World!" << std::endl;
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

1.2 使用动态库

1) .dll
注意:.dll需要放在cmake-build-debug目录下

定义dll源文件

#include<Windows.h>
extern "C"  _declspec(dllexport) int add(int x, int y);
#include <iostream>
#include "lib.h"

int add(int x, int y){
    return x + y;
}

调用.dll

#include <iostream>
#include<Windows.h>

using namespace std;

int main(){
    typedef int(*lpAddFun)(int,int); //宏定义函数指针类型
    HINSTANCE hModule = LoadLibrary("D:\\pwc\\sdp\\cmake-build-debug\\sdp.dll");//DLL句柄
    lpAddFun addFun; //函数指针
    int result=0;//将函数返回的值赋给它,这里先初始化

    if (hModule != NULL) {
        addFun = (lpAddFun)GetProcAddress(hModule, "add");/*用addFun取代dll库中的add函数*/

        if (addFun != NULL) {
            result = addFun(2, 3);//这里是将整型2和整型3作为参数传进去

            cout << "返回结果:";
            cout << result << endl;
        } else {
            cout << GetLastError() ;
        }
    }
    FreeLibrary(hModule);
}

2).so

定义so源文件:

extern "C" int add(int x, int y);
#include "so.h"

extern "C" int add(int x, int y){
    return x + y;
}

调用so

此处so文件放在和执行文件同一个目录下

#include <iostream>
#include <dlfcn.h>

using namespace std;

int main() {

    cout << "Hello World!1" << endl;

    void* handle = dlopen("./a.so", RTLD_LAZY);

    if (NULL == handle){
        cout << "handle is null!" << endl;
        return -1;
    }
    typedef int (*add_t)(int, int);

    add_t add = (add_t) dlsym(handle, "add");

    if (NULL == add) {
        cout << "add is null!" << endl;
        return -1;
    }
    int i = add(10, 10);

    cout << "结果:" << i << endl;

    dlclose(handle);
    return 0;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值