新西兰服务器

C++ DLL怎么导出


C++ DLL怎么导出

发布时间:2021-11-26 13:50:10 来源:高防服务器网 阅读:78 作者:iii 栏目:网络安全

本篇内容介绍了“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("%dn", add_ptr(11, 4));      } else {          printf("GetProcAddress add function failed!n");          return 1;      }      if (sub_ptr) {          printf("%dn", sub_ptr(21, 4));      } else {          printf("GetProcAddress sub function failed!n");          return 1;      }      return 0;  }
注意:定义函数指针的类型声明必须与函数定义一致,否则无法正常使用。

“C++ DLL怎么导出”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注高防服务器网网站,小编将为大家输出更多高质量的实用文章!

[微信提示:高防服务器能助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

[图文来源于网络,不代表本站立场,如有侵权,请联系高防服务器网删除]
[