使用GetProcAddress 获取DLL里面的类的static成员函数地址

忘世麒麟 2020-07-02 02:07:37
我在学习如何从dll中获取函数地址,我发现一个问题: 对于不是属于类的函数,可以很容易的获取地址,但是假如一个函数是属于类的,哪怕是静态的,也无法获取地址.代码如下:
实现是dll的头文件,dll生成好了
#pragma once
#ifdef __cplusplus
extern "C" {
#endif

#ifdef DLL_TRAINING_API
#else
#define DLL_TRAINING_API _declspec(dllimport)
#endif

class DLL_TRAINING_API arithmetic_operation
{
public:
static arithmetic_operation* createApi();
double Add(double a,double b);
double Sub(double a,double b);
double Multi(double a,double b);
double Div(double a,double b);
};
int DLL_TRAINING_API export333();

#ifdef __cplusplus
}
#endif


然后是我解析dll的代码
#include <iostream>
#include "selfTrainingDll.h"
#include <windows.h>
using namespace std;

int main()
{
// 定义函数地址
typedef int(*_print)();

// 定义static成员的函数指针
typedef arithmetic_operation* (*_createApi)() ;

// 加载DLL
HINSTANCE hDll = LoadLibrary(L"DllTest.dll");

// 成功了
_print export333 = (_print)GetProcAddress(hDll, "export333");
cout << export333() << endl;

// 返回0 --- 失败了
_createApi createObj = (_createApi)GetProcAddress(hDll,"createApi");

// 无法调用 -- 失败了
arithmetic_operation* objPtr = createObj();

// 释放DLL
FreeLibrary(hDll);
}


如我所注释的 :export333( ) 是一个类外的函数,所以,获取地址很简单;
但是我想获取类中的静态成员函数,就失败了.


请问我哪里写错了,还是说属于类的成员函数,用dll封装后,都无法获取地址呢?
谢谢!!!!
...全文
1697 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
走好每一步 2020-07-03
  • 打赏
  • 举报
回复
导出类,用lib的方式加载符号
  • 打赏
  • 举报
回复
引用 10 楼 忘世麒麟 的回复:
[quote=引用 9 楼 早打大打打核战争 的回复:]c++符号名有所谓的name mangling,所以你要么使用它的实际导出名,要么建立一个别名导出,有两种方法
一是在.def文件中
exports
Add=实际c++名
或者在dll的源文件中直接写
#pragma comment(linker, "/export:Add=实际c++名”)

多谢指点,但是,有一个问题是,大多数情况下处理的都是第三方的dll文件,是没有办法更改他们的源码的.哈哈哈,好难啊[/quote]

用宏重新定义一下你爱用的符号名即可
真相重于对错 2020-07-02
  • 打赏
  • 举报
回复
另外类静态函数和全局函数做成友元,有何区别,非要把他做成类函数不是自讨苦吃?
真相重于对错 2020-07-02
  • 打赏
  • 举报
回复
这种原生的dll本来就没有面向对象的概念,他是为c准备的,不要妄想能用c++把他们完美的结合在一起,那篇文章的也指出了这一点,就算你能结合,也无法把c++的特性完全利用到,不如直接用c,否则出了错你都不知道如何出的。c++只有基于源程序的标准,对于二进制可执行文件各个厂家有其自有的标准,而dll是为了二进制的复用。所以用dll最好不要用c++交互,而是内部c++,外部c。 还有微软之前搞过基于c++的dll 交互,好像是用mfc扩展类,后来好像搁置了,面向对象的二进制复用,微软支持的是com,后来的.net.那个才是正道。
忘世麒麟 2020-07-02
  • 打赏
  • 举报
回复
引用 9 楼 早打大打打核战争 的回复:
c++符号名有所谓的name mangling,所以你要么使用它的实际导出名,要么建立一个别名导出,有两种方法
一是在.def文件中
exports
Add=实际c++名
或者在dll的源文件中直接写
#pragma comment(linker, "/export:Add=实际c++名”)

多谢指点,但是,有一个问题是,大多数情况下处理的都是第三方的dll文件,是没有办法更改他们的源码的.哈哈哈,好难啊
  • 打赏
  • 举报
回复
c++符号名有所谓的name mangling,所以你要么使用它的实际导出名,要么建立一个别名导出,有两种方法
一是在.def文件中
exports
Add=实际c++名
或者在dll的源文件中直接写
#pragma comment(linker, "/export:Add=实际c++名”)
忘世麒麟 2020-07-02
  • 打赏
  • 举报
回复
引用 1 楼 早打大打打核战争 的回复:
GetProcAddress只能获取DLL中导出的函数地址

链接贴错了,是这个 https://www.codeproject.com/Articles/9405/Using-classes-exported-from-a-DLL-using-LoadLibrar
忘世麒麟 2020-07-02
  • 打赏
  • 举报
回复
引用 6 楼 忘世麒麟 的回复:
[quote=引用 5 楼 真相重于对错 的回复:]类函数编译后,会改变名称,所以不能通过getprocessaddress方式拿到,需要导出lib,方式

在第三楼我都贴出例子来了.我再贴一遍. https://stackoverflow.com/questions/16011945/dll-load-and-call-class-method
前面一楼我都说了,我已经将类成员函数的函数地址搞定了.现在剩下了类的static成员函数没搞定......
[/quote]
链接贴错了,是这个 https://www.codeproject.com/Articles/9405/Using-classes-exported-from-a-DLL-using-LoadLibrar
忘世麒麟 2020-07-02
  • 打赏
  • 举报
回复
引用 5 楼 真相重于对错 的回复:
类函数编译后,会改变名称,所以不能通过getprocessaddress方式拿到,需要导出lib,方式

在第三楼我都贴出例子来了.我再贴一遍. https://stackoverflow.com/questions/16011945/dll-load-and-call-class-method
前面一楼我都说了,我已经将类成员函数的函数地址搞定了.现在剩下了类的static成员函数没搞定......
真相重于对错 2020-07-02
  • 打赏
  • 举报
回复
类函数编译后,会改变名称,所以不能通过getprocessaddress方式拿到,需要导出lib,方式
忘世麒麟 2020-07-02
  • 打赏
  • 举报
回复
引用 3 楼 早打大打打核战争 的回复:
DLL的设计就是通过名字/序号导出地址,该地址存储的是什么东西无所谓,代码、数据都可以,前提是你得导出

我想请教一个实际的问题: 我希望能获取里面的static成员,应该如何操作,或者我的def文件中应该如何写这个static成员.我现在对普通成员函数地址已经可以拿到了,但是static的还是拿不到.
我猜测可能是def文件写错了.我是这样写的:
LIBRARY "DllTest"
EXPORTS
createApi
Add
Sub
Multi
Div
export333
请问你有什么思路吗
  • 打赏
  • 举报
回复
DLL的设计就是通过名字/序号导出地址,该地址存储的是什么东西无所谓,代码、数据都可以,前提是你得导出
忘世麒麟 2020-07-02
  • 打赏
  • 举报
回复
引用 1 楼 早打大打打核战争 的回复:
GetProcAddress只能获取DLL中导出的函数地址
导出类也可以 参考 https://stackoverflow.com/questions/16011945/dll-load-and-call-class-method

  • 打赏
  • 举报
回复
GetProcAddress只能获取DLL中导出的函数地址

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧