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 }
以上是关于Windows中的库编程的主要内容,如果未能解决你的问题,请参考以下文章