C和C++中动态链接库的创建和链接

1.创建DLL(动态链接库)-C++方式

1.创建DLL(动态链接库-C++方式)

1.在VS(以VS2017为例)中创建DLL动态链接库。



解决方案名称为:MyDLL

项目名称为:Dll1

2.创建头文件Dll1.h

输入如下代码:

#pragma once
#ifdef MY_DLL_EXP
#else
#define MY_DLL_EXP _declspec(dllimport)////当编译时,头文件不参加编译,所以.cpp文件中先定义,后头文件被包含进来,因此外部使用时,为dllexport,而在内部编译时,则为dllimport
#endif
//创建一个常量
MY_DLL_EXP extern const double PI;
//创建一个测试用的函数
void MY_DLL_EXP Hello();
//创建一个测试用的类
class MY_DLL_EXP Calculate {
public:
double add(double a, double b);
double sub(double a, double b);
double mult(double a, double b);
double divd(double a, double b);
};

3.创建Dll1.cpp(如存在则不用创建)

输入如下代码:

#include "stdafx.h"
#include "Dll1.h"
//注意以上两个头文件的相对顺序不能改变
#include <iostream>
#define MY_DLL_EXP _declspec(dllexport)
//导出常量
const double PI = 3.14;
//导出函数
void Hello() {
std::cout << "Hello World!" << std::endl;
}
//导出类中的函数
double Calculate::add(double a, double b) {
return a + b;
}
double Calculate::sub(double a, double b) {
return a - b;
}
double Calculate::mult(double a, double b) {
return a * b;
}
double Calculate::divd(double a, double b) {
if (b == 0)
return 0;
return a / b;
}

4.生成即可完成C++版动态链接库的创建

注意:动态链接库文件不能直接执行

2.链接DLL(动态链接库-C++方式)

1.隐式链接

1.准备

Dll1.h(Dll1项目目录中)

Dll1.lib(解决方案的Debug中)

Dll1.dll(结局方案的Debug中)

2.创建一个测试用隐式链接动态链接库的项目

此处以空项目为例



项目名称为:testDll1

此处为了方便,将Dll1.h,Dll1.lib,Dll1.dll放入到新建的项目目录下。

3.右击解决方案,选择属性。在通用属性中的启动项目中选择当前选中内容,确认即可。



4.右击要链接DLL的项目testDll1,选择属性,进行配置。

(1)配置属性->VC++目录->在"包含目录"里添加头文件Dll1.h所在的目录







(2)配置属性->VC++目录->在"库目录"里添加头文件Dll1.lib所在的目录





(3)配置属性->链接器->输入->在"附加依赖项"里添加Dll1.lib(若有多个lib则以空格隔开)





4.将Dll1.dll文件放入到创建的项目的目录下或是解决方案的Debug目录下

5.创建testDll1.cpp

输入如下测试代码:

#include "Dll1.h"
#include <iostream>
//隐式调用DLL
using namespace std; int main() {
cout << PI << endl;//测试输出常量
Hello();//测试函数
//测试类
Calculate calc;
cout << "3 + 2 = " << calc.add(3, 2) << endl;
cout << "4 - 1 = " << calc.sub(4, 1) << endl;
cout << "3 * 2 = " << calc.mult(3, 2) << endl;
cout << "4 / 2 = " << calc.divd(4, 2) << endl;
cin.get();//暂停
}

输出结果:

2.显式链接

显示链接可以在执行过程中随时加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适.

显示链接主要是使用LoadLibrary()函数。此处只说明显示链接DLL的导出函数的使用方法,导出类的使用比较复杂,将在我的其他文章中说明。

1.创建测试用空项目testDll2

2.将Dll1.dll放入到testDll2项目目录下

3.创建testDll2.cpp

输入如下代码:

//显示链接DLL-使用GetProcAddress获取函数的名字会有所改变需要使用dumpbin.exe查询
#include <Windows.h>//加载头文件
#include <iostream> using namespace std;
//设置全局变量hInst用于存储dll句柄并加载动态链接库
HINSTANCE hInst = nullptr;
//声明函数指针
typedef void(*Hello)(); int main() {
//加载动态链接库D111.dll
hInst = LoadLibrary("Dll1.dll");
if (hInst == nullptr) {
cout << "动态链接库加载失败!!!" << endl;
FreeLibrary(hInst);
cin.get();
return 0;
}
//加载导出函数,此处函数名有所不同,需要使用dumpbin.exe进行查询
Hello hello = (Hello)GetProcAddress(hInst, "?Hello@@YAXXZ");
cout << "Hello()=";
hello();
cin.get();
//释放动态链接库
FreeLibrary(hInst);
return 0;
}

4.查询函数名称的方法

使用dumpbin.exe查询

打开VS的自带的本机工具命令提示



打开之后的界面:



进入Dll1.dll所在路径





在控制台中输入dumpbin -exports Dll1.dll进行查询





Hello函数的函数名为?Hello@@YAXXZ

5.生成并运行

运行结果

2.创建DLL(动态链接库-C方式)

1.创建DLL(动态链接库-C方式)

1.创建动态链接库项目,名称为Dll2

2.创建Dll2.h

输入如下代码

#pragma once
#ifdef MY_DLL_EXP
#else
#define MY_DLL_EXP _declspec(dllimport)////当编译时,头文件不参加编译,所以.cpp文件中先定义,后头文件被包含进来,因此外部使用时,为dllexport,而在内部编译时,则为dllimport #endif
//导出函数Add
extern "C" MY_DLL_EXP double Add(double a, double b);

3.创建Dll2.cpp(如果有则不需要创建)

输入如下代码:

#include "stdafx.h"
#include "Dll2.h"
//注意以上两个头文件的相对顺序不能改变
#define MY_DLL_EXP _declspec(dllexport) double Add(double a, double b) {
return a + b;
}

4.生成即可。

2.链接DLL(动态链接库-C方式)

1.隐式链接

1.准备

Dll2.dll(解决方案Debug目录下)

Dll2.lib(解决方案Debug目录下)

2.创建测试项目testDll3

3.把Dll2.dll和Dll2.lib放入到testDll3项目目录下

4.创建testDll3.cpp

输入如下代码:

//隐式调用
#include <iostream>
#pragma comment(lib,"Dll2.lib") using namespace std;
//载入函数,此处起到头文件的作用
extern "C" _declspec(dllimport) double Add(double a, double b); int main() {
cout << "Add(3,4)=" << Add(3, 4) << endl;
cin.get();
return 0;
}

5.生成并运行

运行结果:

2.显式链接

1.新建测试项目testDll4

2.把Dll2.dll放入新建的项目testDll4目录中

3.新建testDll4.cpp

创建dll过程中使用C编译器来编译函数,这样DLL文件中的函数名和原dll工程中的函数名就一致了。

墙裂推荐此种方式

输入如下代码:

//显示链接DLL-C
#include <Windows.h>//加载头文件
#include <iostream> using namespace std;
//设置全局变量hInst用于存储dll句柄并加载动态链接库
HINSTANCE hInst = nullptr;
//声明函数指针
typedef double(*Add)(double a,double b); int main() {
//加载Dll2.dll
hInst = LoadLibrary("Dll2.dll");
if (hInst == nullptr) {
cout << "动态链接库加载失败!!!" << endl;
FreeLibrary(hInst);
cin.get();
return 0;
}
//加载函数
Add add = (Add)GetProcAddress(hInst, "Add");
cout << "Add(3,4)="<<add(3,4)<<endl;
cin.get();
FreeLibrary(hInst);
return 0;
}

4.生成并运行。

C和C++中动态链接库的创建和链接(原创,装载请注明原处)的更多相关文章

  1. Java使用JNA方式调用DLL(动态链接库)(原创,装载请注明出处)

    Java使用JNA调用DLL 1.准备 1.JDK环境 2.Eclipse 3.JNA包 下载JNA包: (1).JNA的Github:https://github.com/java-native-a ...

  2. C/C++中动态链接库的创建和调用

    DLL 有助于共享数据和资源.多个应用程序可同时访问内存中单个DLL 副本的内容.DLL 是一个包含可由多个程序同时使用的代码和数据的库.下面为你介绍C/C++中动态链接库的创建和调用. 动态连接库的 ...

  3. [转贴] C/C++中动态链接库的创建和调用

    DLL 有助于共享数据和资源.多个应用程序可同时访问内存中单个DLL 副本的内容.DLL 是一个包含可由多个程序同时使用的代码和数据的库.下面为你介绍C/C++中动态链接库的创建和调用. 动态连接库的 ...

  4. linux中动态链接库的创建与使用

    LINUX系统中动态链接库的创建与使用 http://www.cnblogs.com/ardar/articles/357321.html 正常C源文件编写,编译时-shared即可得到SO, gcc ...

  5. LINUX系统中动态链接库的创建与使用

    大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部 ...

  6. LINUX系统中动态链接库的创建与使用{补充}

    大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部 ...

  7. Linux与Windows中动态链接库的分析与对比

    摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理.但不同操作系 ...

  8. [转]Delphi 中动态链接库(dll)的建立和使用

    动态链接库是一个能够被应用程序和其它的DLL调用的过程和函数的集合体,它里面包含的是公共代码或资源.由于DLL代码使用了内存共享技术,在某些地方windows也给了DLL一些更高的权限,因而DLL中可 ...

  9. Delphi中DLL的创建和使用(转)

    Delphi中DLL的创建和使用     1.DLL简介:   2.调用DLL:   3.创建DLL:   4.两个技巧:   5.初始化:   6.例外处理.            1.DLL简介  ...

随机推荐

  1. 实现node端渲染图表的简单方案

    实现node端渲染图表的简单方案 这个题目有点小,本篇博客真正谈论的应该是服务端生成图表的简单方案,这里面有两个关键字:服务端 & 简单,我们知道基于js有很多的图表库,知名的如D3.echa ...

  2. sublime text3 注册码

    —– BEGIN LICENSE —– TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA ...

  3. bzoj 4557: [JLoi2016]侦察守卫【树形dp】

    设f[u][i]为u点向下覆盖至少i层并且处理完u的子树的最小代价,f[u][i]为u点向上覆盖至少i层并且处理完u的子树的最小代价 转移的话显然f[u][i]+=f[v][i-1],但是f[u][0 ...

  4. HTML实现单行时文字居中,多行文字时左对齐显示效果

    css代码: div { width: 100px; padding: 5px; text-align: center; background-color: #5dffa0; } p { paddin ...

  5. 不常见偏门的Bug,Spring Boot IDEA 静态资源 图片访问404,初学者之殇

    用过Idea朋友都知道,它有一个非常让人喜欢的功能就是:打算在某个a目录下创建一个hello.class文件,那么你仅需要右键点击New-Java Class- 然后输入名字:a.hello 即可. ...

  6. PHP gd 库添加 freetype

    gd 库未安装 freetype 可能导致验证码图片加载不出来等问题. 先到 PHP 的扩展目录里面找到 gd 扩展文件夹 最好先 make clean 清除之前编译的可执行文件及配置文件,运行/us ...

  7. windows 异步通知I/O模型与重叠I/O模型

    一.异步IO模型(asynchronous IO) (1)什么是异步I/O 异步I/O(asynchronous I/O)由POSIX规范定义.演变成当前POSIX规范的各种早起标准所定义的实时函数中 ...

  8. [NOIP2018校模拟赛]T1聚会 party

    题目链接: 聚会 分析: 设每个点到1号点的距离为dist_{i},每个点的权值为x_{i},目标点到1号点的距离为dist,权值为x,那么对于每一次查询,我们讨论三种情况: ① 目标家庭在区间左边( ...

  9. noip初赛

    运算符       联结词名称 异或 ⊕       非¬(-)     否定 与∧(·) 对应集合∩交集 对应按位与符号& 合取 或∨(+) 对应集合∪并集 对应按位或符号| 析取 条件→ ...

  10. BestCoder Round #54 (div.2) 1003 Geometric Progression

    题目传送门 题意:判断是否是等比数列 分析:高精度 + 条件:a[i] * a[i+2] == a[i+1] * a[i+1].特殊情况:0 0 0 0 0是Yes的,1 2 0 9 2是No的 代码 ...