Windows中的库编程

Posted zhaotianff

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows中的库编程相关的知识,希望对你有一定的参考价值。

在上一篇文章(https://www.cnblogs.com/zhaotianff/p/10797057.html)中介绍了如何对全局函数进行导出,

 

这篇文章再补充一下如何导出变量、类及DllMain函数的介绍

 

导出变量

说明:

1、这里的变量指的是全局变量或类静态变量

2、当导出一个变量或类时,载入此dll的程序将会获得单独的拷贝,因此各程序之间不会影响。

 

导出全局变量

使用模块定义文件导出(.def)

1.创建一个C++动态链接库工程

 

2.添加lib_demo.cpp,添加两个变量

1 int global_variable = 100;
2 int global_variable_2 = 102;

3.添加一个模块定义文件

输入

1 LIBRARY
2 EXPORTS
3 global_variable CONSTANT
4 global_variable_2 CONSTANT

 

说明:

使用CONSTANT会提示关键字已过时,可参阅

https://docs.microsoft.com/en-us/cpp/build/importing-using-def-files?view=msvc-160

 

4.编译工程,生成lib_demo.dll和lib_demo.lib

5.创建一个控制台应用程序lib_demo_def_test,输入以下代码

 1 #include <iostream>
 2 
 3 extern int global_variable;  //因为没有用__declspec(dllimport),所以认为global_variable为指针
 4 extern int __declspec(dllimport) global_variable_2;
 5 
 6 int main()
 7 {
 8     //输出导出变量
 9     std::cout << *(int*)global_variable << std::endl;
10 
11     //赋值操作
12     *(int*)global_variable = 88;
13 
14     //输出赋值后的值 
15     std::cout << *(int*)global_variable << std::endl;
16 
17 
18     //输出导出变量
19     std::cout << global_variable_2 << std::endl;
20 
21     //赋值操作
22     global_variable_2 = 77;
23 
24     //输出赋值后的值 
25     std::cout << global_variable_2 << std::endl;
26 }

 

 

 

使用__declspec(dllexport)方式导出

 

1.创建一个C++动态链接库工程

2.添加lib_demo.h,使用__declspec(dllexport)声明要导出的全局变量

1 #ifdef indll
2 #define export_api __declspec(dllexport)
3 #else
4 #define export_api __declspec(dllimport)
5 #endif
6 
7 export_api extern int global_variable;
8 export_api extern int global_variable_2;

3.添加lib_demo.cpp,定义两个全局变量

1 #ifndef indll
2 #define indll
3 #endif // !indll
4 
5 #include"lib_demo.h"
6 
7 //定义两个全局变量
8 int global_variable = 100;
9 int global_variable_2 = 102;

 

说明:

  • 在dll工程中,定义indll,这样export_api就是__declspec(dllexport),而在调用工程中,没有定义indll,export_api就是__declspec(dllimport)
  • lib_demo.h只对要导出的变量进行声明,所以要用extern。lib_demo.cpp中对变量进行定义。
  • 需要先定义indll,再包含头文件

 

4.编译工程,生成.dll和.lib文件

5.创建一个控制台应用程序lib_demo_dllexport_test,输入以下代码

 1 #include <iostream>
 2 #include "../lib_demo_dllexport/lib_demo.h"
 3 
 4 #pragma comment(lib,"..\\\\Debug\\\\lib_demo_dllexport.lib")
 5 
 6 int main()
 7 {
 8     std::cout << global_variable << std::endl;
 9     std::cout << global_variable_2 << std::endl;
10 
11     global_variable = 88;
12     global_variable_2 = 99;
13 
14     std::cout << global_variable << std::endl;
15     std::cout << global_variable_2 << std::endl;
16 }

 

 

导出类静态变量(__declspec(dllexport)方式)

1.创建一个C++动态链接库工程

2.添加lib_demo.h,创建一个CLibTest类

 1 #define export_api __declspec(dllexport)
 2 #else
 3 #define export_api __declspec(dllimport)
 4 #endif
 5 
 6 class CLibTest
 7 {
 8 public:
 9     CLibTest();
10     ~CLibTest();
11 
12 public:
13     static double ID;   //定义一个类静态变量
14 };

3.添加lib_demo.cpp,实现CLibTest类

 1 #define indll
 2 
 3 #include "lib_demo.h"
 4 
 5 CLibTest::CLibTest()
 6 {
 7 
 8 }
 9 
10 CLibTest::~CLibTest()
11 {
12 
13 }
14 
15 double CLibTest::ID = 520.1314;

4.编译工程,生成.dll和.lib文件

5.创建一个控制台应用程序lib_demo_export_class_static_test,输入

 1 #include <iostream>
 2 #include<stdlib.h>
 3 #include "../lib_demo_export_class_static/lib_demo.h"
 4 
 5 #pragma comment(lib,"../Debug/lib_demo_export_class_static.lib")
 6 
 7 int main()
 8 {
 9     std::cout.precision(7);
10     std::cout << CLibTest::ID << std::endl;
11 }

 

导出类

使用模块定义文件方式导出(.def文件)

1.创建一个C++动态链接库工程

2.添加lib_demo.h,声明类CLibTest

 1 #pragma once
 2 
 3 class CLibTest
 4 {
 5 public:
 6     CLibTest();
 7     ~CLibTest();
 8 
 9 public:
10     int TestMethod1();
11     double TestMethod2();
12 };

3.添加lib_demo.cpp,实现CLibTest

 1 #include"lib_demo.h"
 2 
 3 CLibTest::CLibTest()
 4 {
 5 
 6 }
 7 
 8 CLibTest::~CLibTest()
 9 {
10 
11 }
12 
13 int CLibTest::TestMethod1()
14 {
15     return 520;
16 }
17 
18 double CLibTest::TestMethod2()
19 {
20     return 0.1314;
21 }

4.打开项目属性页,找到【配置属性】-》【链接器】-》【调试】->【生成映射文件】,设置为【是(/MAP)】

5.用记事本打开生成路径下的xxx.map文件,我这里的工程名为lib_demo_class_def,所以打开的是lib_demo_class_def.map文件,

搜索 【lib_demo.obj】。即声明类的头文件名.obj,我这里是lib_demo.h,所以是lib_demo.obj

6.创建一个模块定义文件,输入

1 LIBRARY
2 EXPORTS
3 ??0CLibTest@@QAE@XZ  ;构造函数
4 ??1CLibTest@@QAE@XZ  ;析构函数
5 ?TestMethod1@CLibTest@@QAEHXZ  ;TestMethod1
6 ?TestMethod2@CLibTest@@QAENXZ  ;TestMethod2

EXPORTS后面的部分就是上面在.map文件中搜索到的内容

7.创建一个调用工程lib_demo_class_def_test,输入

 1 #include <iostream>
 2 #include"../lib_demo_class_def/lib_demo.h"
 3 
 4 #pragma comment(lib,"../Debug/lib_demo_class_def.lib")
 5 
 6 int main()
 7 {
 8     CLibTest test;
 9     auto test_result = test.TestMethod1();
10     auto test_restlt_2 = test.TestMethod2();
11 
12     std::cout << test_result << std::endl;
13     std::cout << test_restlt_2 << std::endl;
14 }

 

使用__declspec(dllexport)方式导出

 

1.创建一个C++动态链接库工程

2.创建lib_demo.h,声明CLibTest类

 1 #pragma once
 2 
 3 class __declspec(dllexport) CLibTest
 4 {
 5 public:
 6     CLibTest();
 7     ~CLibTest();
 8 
 9 public:
10     int TestMethod1();
11     double TestMethod2();
12 };

3.创建lib_demo.cpp,实现CLibTest

 1 #include"lib_demo.h"
 2 
 3 CLibTest::CLibTest() {}
 4 
 5 CLibTest::~CLibTest() {}
 6 
 7 int CLibTest::TestMethod1()
 8 {
 9     return 520;
10 }
11 
12 double CLibTest::TestMethod2()
13 {
14     return 0.1314;
15 }

4.创建一个调用工程lib_demo_class_dllexport_test,输入

 1 #include <iostream>
 2 #include"../lib_demo_class_dllexport/lib_demo.h"
 3 
 4 #pragma comment(lib,"../Debug/lib_demo_class_dllexport.lib")
 5 
 6 int main()
 7 {
 8     CLibTest test;
 9     auto result = test.TestMethod1();
10     auto result_2 = test.TestMethod2();
11 
12     std::cout << result << std::endl;
13     std::cout << result_2 << std::endl;
14 }

 

示例代码

 

life runs on code

作者: zhaotianff

转载请注明出处

以上是关于Windows中的库编程的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——JS中的面向对象编程

VSCode自定义代码片段9——JS中的面向对象编程

使用 Pygments 检测代码片段的编程语言

有没有办法以编程方式使用kotlin更改片段中的文本颜色?

使用 Git 来管理 Xcode 中的代码片段

片段中的 super.onCreateView