使用vs封装c++成dll和lib

dll和lib

简介

  • DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”。在很多Windows程序中包含有许多dll文件,在程序运行时调用。有着消耗资源比较少,动态加载,程序模块化和简化安装和部署的特点。
  • Static library .lib是一种文件名后缀,代表的是静态数据连接库,在windows操作系统中起到链接程序和函数(或子过程)的作用,相当于Linux中的·a或·o、.so文件。
  • 简单的区分两者就是,dll是运行时用,lib是编译的时候使用。一般的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。

托管与非托管

  • 托管代码是一microsoft的中间语言(IL),他主要的作用是在.NET FRAMEWORK的公共语言运行库(CLR)执行代码前去编译源代码,不用自行提供垃圾回收、类型检查、安全支持等服务。如c#
  • 非托管代码在公共语言运行库环境的外部,由操作系统直接执行的代码。非托管代码必须提供自己的垃圾回收、类型检查、安全支持等服务,如C++,C。
    如果c#想要调用c++,就需要吧c++封装成dll

debug和release

使用vs开发程序的时候,有debug和release两个模式的调试。debug版本的调试结果包含这调试的信息,程序自然也比较大,而release版本是经过编译的优化的,也不包含调试的信息,体积相对debug版本小得多,开发时需要经常验证release模式是否能正常运行。

封装

  1. vs新建win32项目

![win32](https://img- blog.csdn.net/20180418210108955?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21hbmdvX2hhb21pbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

  1. 选择dll

![dll](https://img- blog.csdn.net/20180418210215999?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21hbmdvX2hhb21pbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

工程新建好之后看一下官方自带的封装导出demo.

头文件是这样的


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 下列 ifdef 块是创建使从 DLL 导出更简单的

// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 CREATDLL_EXPORTS

// 符号编译的。在使用此 DLL 的

// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将

// CREATDLL_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的

// 符号视为是被导出的。

#ifdef CREATDLL_EXPORTS

#define CREATDLL_API __declspec(dllexport)

#else

#define CREATDLL_API __declspec(dllimport)

#endif

// 此类是从 creatDll.dll 导出的

class CREATDLL_API CcreatDll {

public:

CcreatDll(void);

// TODO: 在此添加您的方法。

};

extern CREATDLL_API int ncreatDll;

CREATDLL_API int fncreatDll(void);

然后对应的cpp文件是这样的


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// creatDll.cpp : 定义 DLL 应用程序的导出函数。

//

#include "stdafx.h"

#include "creatDll.h"

// 这是导出变量的一个示例

CREATDLL_API int ncreatDll=0;

// 这是导出函数的一个示例。

CREATDLL_API int fncreatDll(void)

{

return 42;

}

// 这是已导出类的构造函数。

// 有关类定义的信息,请参阅 creatDll.h

CcreatDll::CcreatDll()

{

return;

}

学习官方的demo可以知道,
导出的类声明应该时这样的


1
2
3
4
5
6
7
class __declspec(dllexport)  class_name

{

......//members

}

然后类的函数定义是这样的


1
2
3
4
5
6
7
return_type class_name::function_name()

{

...//body

}

导出变量声明


1
extern __declspec(dllexport) type variavle_name;

导出变量初始化


1
extern __declspec(dllexport) type variavle_name = value;

导出函数的声明


1
extern __decspec(dllexport) return_type function_name(type valure);

导出函数定义


1
2
3
4
5
6
7
extern __decspec(dllexport) return_type function_name(type valure)

{

...//body

}

  1. 添加.h头文件

学习了官方示例后,我们可以自建头文件如:


1
2
3
4
5
6
7
8
9
#ifndef DLL_H

#define DLL_H

extern __declspec(dllexport)int add(int x, int y);

extern __declspec(dllexport)int sub(int x, int y);

#endif

  1. 添加.cpp文件

对应的cpp文件


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include"stdafx.h"

#include"dll.h"

int add(int x, int y)

{

return x + y;

}

int sub(int x, int y)

{

return x - y;

}

  1. 编译生成

![dll](https://img- blog.csdn.net/20180418211719679?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21hbmdvX2hhb21pbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

vc调用测试

新建vs空工程

添加main.cpp文件


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//use the dll file

#include<iostream>

#include"dll.h"

#include"creatDll.h"

using namespace std;

int main(int argc, char** argv)

{

CcreatDll c1;

cout<<ncreatDll<<endl;

cout<<add(1, 2)<<endl

<<sub(6, 3)<<endl;

getchar();

return 0;

}

先编译一下,拷贝creatDll.dll到工程的Debug目录下,注意是整个工程的Debug目录。

dll.h、creatDll.h(封装项目含有导出代码声明的两个头文件)这两个头文件拷贝到与main.cpp同目录下,新建include文件夹,移动两个头文件进去。

然后拷贝creatDll.lib文件到main.cpp文件同目录,新建lib文件夹,移动creatDll.lib进去。

项目属性配置包含目录./include 库目录./lib

编译,调试。

![result](https://img- blog.csdn.net/2018041821323816?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21hbmdvX2hhb21pbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

-------------本文结束感谢您的阅读-------------