跳转至

动态库和静态库

3种库加载方式 - 动态库静态加载 - 动态库动态加载 - 静态库加载

title: linux和windows下静态库动态库后缀
- windows:
  - 静态库:xxx.lib
  - 动态库:xxx.dll
- Linux:Linux上库命名格式,以lib起始,xxx表示库名,.a结尾是静态库,.so结尾是动态库
  - 静态库:libxxx.a(.a代表achieve)
  - 动态库:libxxx.so(.so代表share object)
title: windows下生成dll时会附带lib
在生成动态库时也会生成一个lib文件,但这个lib文件与静态库lib文件内容是不一样的。此时的lib文件称导*动态库入库*,主要含动动态库接口入口等信息,而函数主要实现还是在动态库dll文件中。而静态库lib类似于将可执行程序打包,里面是含有完完整整的实现。

1.1 动态库静态加载

特点:使用lib和dll,不使用库函数调用dll来导入接口实现。

1.1.1 第一步:生成dll、lib

  1. 新建vs项目
  2. 添加.h .cpp文件
  3. 设置vs项目属性
  4. 更改配置属性为动态态库,选择,项目->属性->常规->配置类型->动态库(dll)
  5. 添加编译宏,选择,“项目->属性->C/C++ ->预处理器->预处理器定义”中添加 APIEXPORT 宏
  6. 生成解决方案

  7. add.h文件内容

#pragma once

#ifdef APIEXPORT
#define EXTERN_API extern "C" __declspec(dllexport)
#else
#define EXTERN_API extern "C" __declspec(dllimport)
#endif

EXTERN_API int add(int elm1, int elm2);
  • add.cpp文件内容
#include "add.h"

int add(int elm1, int elm2)
{
    return elm1+ elm2;
}

1.1.2 第二步:加载dll、lib

  1. 新建vs项目
  2. 添加主程序入口函数.cpp文件(包含main函数的源文件)
  3. 添加第一步生成dll中的.h文件.dll文件.lib文件
  4. .h .lib可随意放置,使用时,指定正确的路径即可
  5. 放置.dll文件在和.exe文件同一目录下

  6. main.cpp文件内容

//动态库静态加载
#include <iostream>
#include "add.h"//包含头文件
#pragma comment(lib,"../Debug/libMathFunctions.lib")//指定.lib文件的位置
int main()
{
    std::cout<<add(1, 2);
    return 0;
}

1.2 动态库动态加载

1.2.1 第一步:生成dll、lib

此步骤参考动态库静态加载第一步:生成dll、lib

1.2.2 第二步:加载dll

  1. 新建vs项目
  2. 添加主程序入口函数.cpp文件(包含main函数的源文件)

    1. 使用Windows库函数加载dll
    2. LoadLibraryA 加载dll
    3. GetProcAddress 获取函数地址
    4. FreeLibrary 释放句柄
  3. main.cpp文件内容

//动态库动态加载
#include <iostream>
#include <Windows.h>
int main()
{
    HINSTANCE h = LoadLibraryA("libMathFunctions.dll");//第一步
    typedef int(*FunPtr)(int a, int b);//定义函数指针
    if (h == NULL)
    {
        FreeLibrary(h);
        printf("load lib error\n");
    }
    else
    {
        FunPtr funPtr = (FunPtr)GetProcAddress(h, "add");//第二步
        if (funPtr != NULL)
        {
            int result = funPtr(8, 3);
            printf("8 + 3 =%d\n", result);
        }
        else
        {
            printf("get process error\n");
            printf("%d", GetLastError());
        }
        FreeLibrary(h);//第三步
    }
    return 0;
}

1.3 静态库加载

1.3.1 第一步:生成lib

  1. 新建vs项目
  2. 添加.h .cpp文件
  3. 设置vs项目属性
  4. 更改配置属性为动态态库,选择,项目->属性->常规->配置类型->静态库(lib)
  5. 生成解决方案

  6. add.h文件

#pragma once
int add(int elm1, int elm2);
  • add.cpp文件
#include "add.h"
int add(int elm1, int elm2)
{
    return elm1 + elm2;
}

1.3.2 第二步:加载lib

  1. 新建vs项目
  2. 添加主程序入口函数.cpp文件(包含main函数的源文件)
  3. 添加第一步生成lib中的.lib文件.h文件
  4. .lib .h文件可随意放置,使用时,指定正确的路径即可

main.cpp文件

//静态库加载
#include <iostream>
#include "math/add.h"
#pragma comment(lib,"../Debug/libMathFunctions.lib")
int main()
{
    std::cout << add(1, 2);
    return 0;
}

1.3.3 注意事项

  1. 动态库需要使用__declspec(dllexport)导出和 __declspec(dllimport)加载
  2. 静态库不需要__declspec(dllexport)和 __declspec(dllimport)