C++ 动态库和静态库

目的:代码重用

静态库

 

 

 创建头文件testlib.h

#ifndef TESTLIB_H
#define TESTLIB_H
// 防止头文件重复包含
// 条件编译指令
// 加减乘除
int add(int a, int b);

#endif 

创建testlib.cpp

#include "pch.h"
#include "framework.h"
#include "testlib.h"


int add(int a, int b) {
    return a + b;
}

生成解决方案

1>------ 已启动生成: 项目: testlib, 配置: Debug Win32 ------
1>pch.cpp
1>testlib.cpp
1>testlib.vcxproj -> C:\Users\My\source\repos\testlib\Debug\testlib.lib
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

 

创建新的控制台项目testdll

 

右键项目,属性,链接器,附加库目录 C:\Users\My\source\repos\testlib\Debug\或相对路径(推荐)

使用lib

#include <iostream>
#include "../../testlib/testlib/testlib.h"
#pragma comment(lib, "testlib.lib")

int main()
{
    printf("请输入两个数字\n");
    int a, b;
    scanf("%d%d", &a, &b);
    printf("add(a, b)=%d\n", add(a, b));
    return 0;
}

 

只需提供头文件和lib文件就可以使用你提供的静态库

 

动态库

 静态库生成的文件全都组合到exe里面

动态库则动态加载,不会嵌入到exe中

vs总文件有好几个G大,但是其exe文件只有几个KB,dll的好处

软件升级,只需要更新动态库重启软件就好了,不需要重新安装新的的编译文件

1.VS2019新建立一个空项目(Project1)

VS有提供dll项目的模板,可是对于我来说反而搞不懂模板中的文档,于是建立空白项目,自己去做简单的配置。

2.解决方案管理器中为项目添加一个头文件,选择新建项

在新建的头文件(testdll.h)中声明要导出的API,添加函数声明

#ifndef TESTDLL_H
#define TESTDLL_H
int add(int a, int b);
int sub(int a, int b);
#endif // !TESTDLL_H

3.添加一个源文件,实现申明的API函数

#include "testdll.h"

int add(int a, int b) {
    return a + b;
}

int sub(int a, int b) {
    return a - b;
}

4.修改项目->项目属性->常规->配置类型为动态库(.DLL)

 

 

生成解决方案

1>------ 已启动生成: 项目: testdll, 配置: Debug x64 ------
1>testdll.cpp
1>testdll.vcxproj -> C:\Users\My\source\repos\Project1\Debug\Prodect1.dll
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

将dll文件拖到dependency walker中

 需要添加,声明导出函数

#pragma once
#ifndef TESTDLL_H
#define TESTDLL_H
__declspec(dllexport) int add(int a, int b);
__declspec(dllexport) int sub(int a, int b);
#endif // !TESTDLL_H

重新生成

 

 

 使用动态库有两种方式

 

隐式调用动态库

在project1项目中添加预定义

 

 

修改  testdll.h

#ifndef TESTDLL_H
#define TESTDLL_H

#ifdef _DLLAPI
  #define DLLAPI __declspec(dllexport) 
#else 
  #define DLLAPI __declspec(dllimport)
#endif // !DLLAPI

int DLLAPI add(int a, int b);
int DLLAPI sub(int a, int b);

#endif // !TESTDLL_H

如果DLLAPI定义了,则DLLAPI是__declspec(dllexport) ,因为刚刚预定义了所以是__declspec(dllexport) 。但在testd项目中我们没有预定义因此是__declspec(dllimport) 。

添加项目testdll

 右键项目,属性,C/C++,常规,附加包含目录

 否则无法导入头文件

#include <iostream>
#include "./testdll.h"
#pragma comment(lib, "Project1.lib")

int main()
{
    printf("请输入两个数字\n");
    int a, b;
    scanf("%d%d", &a, &b);
    printf("add(a, b)=%d\n", add(a, b));
    return 0;
}

右键项目,属性,链接器,附加库目录,C:\Users\My\source\repos\Project1\Debug

 

 

 SDL检查 否

 

 

 运行

 

 

 

显示调用动态库

 

修改testdll.cpp

#include <iostream>
#include "./testdll.h"
//#pragma comment(lib, "Project1.lib")
#include <Windows.h>

// 定义函数指针类型
typedef int (*PADD)(int a, int b);

int main()
{
    printf("请输入两个数字\n");
    int a, b;
    scanf("%d%d", &a, &b);
    // 加载dll文件
    HMODULE hDLL = LoadLibrary(L"C:\\Users\\My\\source\\repos\\Project1\\Debug\\Project1.dll");
    if (hDLL == NULL)
    {
        printf("加载失败\n");
        return 0;
    }
    
    PADD padd = (PADD)GetProcAddress(hDLL, "add");

    printf("add(a, b)=%d\n", padd(a, b));

FreeLibrary(hDLL);
return 0; }

运行程序,会报异常,找不到add函数

查看dependency walker

 

 复制函数名,修改上面程序

 PADD padd = (PADD)GetProcAddress(hDLL, "?add@@YAHHH@Z");

运行正常

 

 C语言可以直接使用add,但C++不行

因此,我们要导入C语言的配置

修改testdll.h

#ifdef _DLLAPI
#define DLLAPI __declspec(dllexport) 
#else 
#define DLLAPI __declspec(dllimport)
#endif // !DLLAPI
extern "C" DLLAPI int add(int a, int b);
extern "C" DLLAPI int sub(int a, int b);
#endif // !TESTDLL_H

重新生成Project1

函数改为add,可正常运行testdll

 

为了这个改名,微软还提供了模块定义文件

头文件testdll.h

#pragma once
#ifndef TESTDLL_H
#define TESTDLL_H

int add(int a, int b);
int sub(int a, int b);

#endif // !TESTDLL_H

添加新建项,代码,模块定义文

LIBRARY Project1
EXPORTS
add
sub

重新生成

运行testdll

 

posted on 2020-06-18 18:09  AI数据  阅读(620)  评论(0编辑  收藏  举报

导航