本篇内容介绍了“C++ DLL怎么导出”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
通常项目中导出 DLL 接口有两种方式:
1. __declspec(dllexport)
导出;
2.*.def
文件导出。
__declspec(dllexport) 导出
在 DLL 导出的函数名称前使用 _declspec(dllexport)
关键字导出函数接口。
test_dll.h
// test_dll.h #ifdef __cplusplus extern "C" { #endif #ifdef DLL_EXPORT #else #define DLL_EXPORT _declspec(dllexport) #endif DLL_EXPORT int add(int a, int b); DLL_EXPORT int sub(int a, int b); #ifdef __cplusplus } #endif
test_dll.cpp
// test_dll.cpp #include "test_dll.h" int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; }
def 文件导出
由于 __declspec(dllexport)
导出接口需要定义一长串的内容,所以 MS 引入 def文件
来导出函数接口。
使用 def文件
相对简单,只需要在项目中增加一个后缀名为 .def 的文件,按照格式将 DLL 需要导出的接口定义在 def 文件即可。
1.定义 .def 文件
test_dll.def
LIBRARY test_dll EXPORTS add @1 sub @2
-
DllName
表示 Dll 的文件名 -
@1
[可选] 指定导出的函数序号。导出多个函数时,需要开发者自定义序号,不能重复。
2.添加 def 文件至工程
3.设置工程属性
在 “属性”->“链接器”->“输入” 配置 模块定义文件
输入 def文件
名称。
4.编译生成 DLL
使用工具查看导出函数名接口,导出接口的顺序与 def文件
定义的序号相同。
存在问题
-
通过工具可以查看导出函数名,暴露接口函数功能。
-
导出的函数名可以任意被访问和使用,即使业务功能被封装在内部代码经过加密处理,但外部接口是公开的,可以被正常调用。造成在不知情,被未经授权的开发者滥用,间接造成损失。
解决方案:导出匿名接口
导出匿名序号接口
匿名导出接口只需要在 def文件
的导出接口名称增加 NONAME
关键字即可,如下:
test_dll.def
LIBRARY test_dll EXPORTS add @1 NONAME sub @2 NONAME
-
NONAME
表示不导出函数名称(匿名)。
使用 CFF Explorer
工具查看导出函数接口名称,函数名称已经被隐藏掉。
访问匿名序号接口
静态链接
和通常工程引用 DLL 的方法相同,引用 .h
,链接 .lib
,运行前将 .dll
文件拷贝至应用运行目录即可。
动态加载
通过动态加载的方式调用DLL接口。
当导出序号时,定义函数指针变得复杂,只能通过静态反编译的方式确定参数数量和类型,定义函数指针。
#include <Windows.h> // 定义函数指针 typedef int (*func_ptr)(int, int); int dynamic_load_dll() { // 动态加载 DLL 文件 HINSTANCE hDll = LoadLibrary("test_dll.dll"); // 定义函数指针变量 func_ptr add_ptr, sub_ptr; if(hDll){ add_ptr = (func_ptr)GetProcAddress(hDll, (LPCSTR)1); // 根据导出序号加载函数(add) sub_ptr = (func_ptr)GetProcAddress(hDll, (LPCSTR)2); // 根据导出需要加载函数(sub) }else{ printf("Load DLL failed!/n"); return 1; } if (add_ptr) { printf("%d/n", add_ptr(11, 4)); } else { printf("GetProcAddress add function failed!/n"); return 1; } if (sub_ptr) { printf("%d/n", sub_ptr(21, 4)); } else { printf("GetProcAddress sub function failed!/n"); return 1; } return 0; }
注意:定义函数指针的类型声明必须与函数定义一致,否则无法正常使用。
“C++ DLL怎么导出”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/226017.html