如何在类内获取一个私有方法的地址?

风里有梦 2008-02-26 02:13:53
如下一个类的方法:

...
public:
void* GetThreadProcAddr();

private:
unsigned __stdcall _ThreadProc( void* pvParam );
...

由于该方法为动态方法(非静态),所以它的地址是不确定的. 动态的方法的地址又是怎样生成的呢? 请教高人指点, 谢谢!
...全文
250 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangyue02135 2008-02-27
  • 打赏
  • 举报
回复
17楼仁兄说的极好。做线程的回调,要想用类的非static的方法,由于调用时需要this指针,唯有将具体对象的地址作为参数传给线程,然后再强制转化为该类的指针才能调用你需要的函数。
Chappell 2008-02-27
  • 打赏
  • 举报
回复
17楼的仁兄所言即是
cnzdgs 2008-02-27
  • 打赏
  • 举报
回复
如果是想创建一个线程,应该定义一个公有的静态方法,在创建线程的时候把类的实例指针作为参数传给线程,在线程中再用这个指针来调类的其它方法。因为类的动态方法在调用时需要把实例指针作为隐含参数传过去,所以即使取得函数地址也不能简单地调用。
风里有梦 2008-02-27
  • 打赏
  • 举报
回复
非常感谢Treazy贴出的文章!非常感谢大家的回复!
baihacker 2008-02-26
  • 打赏
  • 举报
回复
又试了几下,还是没有骗过编译器,暂时只有public的函数给出地址了..
Treazy 2008-02-26
  • 打赏
  • 举报
回复
给你贴篇文章,好好看看吧,应该会有所收获的

http://www.codeproject.com/KB/cpp/FastDelegate.aspx
baihacker 2008-02-26
  • 打赏
  • 举报
回复

#include <iostream>
using namespace std;
class A
{
int a;
public:
typedef void (A::* PF)();
static PF GetFoo(){return &A::foo;}
private:
void foo()
{
cout << this << endl;
cout << "A::foo()" << endl;
}
};

int main()
{
(((A*)0)->*A::GetFoo())();
return 0;
}
hastings 2008-02-26
  • 打赏
  • 举报
回复
11楼的代码在VC上能运行,但在Dev-C++上不能运行。
由此可见,这种取成员函数地址并强制进行类型转型的行为是危险的。
sheenl 2008-02-26
  • 打赏
  • 举报
回复
原来是想拿来做线程的回调函数,
别费力气了,简单的方法是做一个静态函数包裹一下
hastings 2008-02-26
  • 打赏
  • 举报
回复
如何在类内获取一个私有方法的地址?
////////////////////////////////
在C++对象模型中有提到。
这涉及类的内存布局,分很多种情况:
普通类,单继承的类,多重继承的类,有虚函数的类,
有虚基类的类等等。
以下例子只是普通类的情况:
class A
{
public:
void fun()
{
cout<<"A::fun()\n";
}
void foo()
{
cout<<"A::foo()\n";
}
};
typedef void (A::* PF)();
typedef void (*F)();
int main()
{
char str[64];
PF pf1=&A::fun;
PF pf2=&A::foo;
sprintf(str,"%p\t%p",pf1,pf2);
printf("%s\n",str);
long a,b;
sscanf(str,"%x%x",&a,&b);
cout<<a<<'\t'<<b<<'\n';
F f1=(F)a;
F f2=(F)b;
f1();
f2();
return 0;
}

若要获取私有方法的地址,则可以在开头处#define private public
^_^。。。。
erwin1984 2008-02-26
  • 打赏
  • 举报
回复
void* GetThreadProcAddr(){ return (void *)_ThreadProc; }
  • 打赏
  • 举报
回复
刚才由于没环境随便写写的,问题比较多。
这样应该就差不多了

struct test
{
int mx;
public:
test(int x):mx(x)
{

}
int __stdcall print()
{
return printf("%d\n",mx);
}
};

int(__stdcall *F)(test*);

int main()
{
test * p = new test(10);
F pf = (F)&test::print;
pf( p );
return 0;
}
  • 打赏
  • 举报
回复
VC的话你可以参考COM所采用的方法。
这个依赖编译器,只能在某些编译器上通过,属于不推荐做法。

struct test
{
int mx;
public:
test(int x):mx(x)
{

}
int stdcall print()
{
return printf("%d\n",mx);
}
};

int(*F)(test*);

int main()
{
test * p = new test(10);
F *pf = (F*)&test::print;
pf( p );
return 0;
}
  • 打赏
  • 举报
回复
sizeof(成员函数指针);
这个结果在不同编译器上结果是不同的,有的是8。
如果是8的话如何处理?

你看一下深入探索C ++对象模型就知道了成员函数和普通函数的区别了。
当然如果你只是在VC 下用,可以直接将成员函数强制转化成一个函数指针。
taodm 2008-02-26
  • 打赏
  • 举报
回复
没有“正规”办法。要么用static成员函数要么用指向成员的指针。
风里有梦 2008-02-26
  • 打赏
  • 举报
回复
TO 3楼:

根据反汇编的代码, 地址好像是固定. 但为什么说不要对成员函数取地址呢? 因为我想写一个线程管理类, 这个管理类主要职责就是创造一批工人,来生产某些物品...

因为我试过, 若是静态方法,用_beginthreadex可成功! 但是, 动态方法却有问题, 我知道, 动态方法是在执行时, 动态创建的(也就是说, 是基于编译后的机器代码规划的). 按理说, 既使是动态方法, 也一样能取到地址!但是为什么取不到呢?

如果能通过this指针来取呢?

请楼上的回答.
pengxn 2008-02-26
  • 打赏
  • 举报
回复
具个例子,抛砖引玉.
===========
vector<string> v1;
....
vector<string>::const_iterator it =
find_if(v1.begin(),vi.end(),mem_fun_ref(&string::empty));

  • 打赏
  • 举报
回复
不管动态方法静态方法,他的地址都是固定的。
只不过不要对成员函数取地址。
风里有梦 2008-02-26
  • 打赏
  • 举报
回复
楼上的纯粹来捣乱...
独孤过儿 2008-02-26
  • 打赏
  • 举报
回复
貌似楼主不知道“方法”这个词的含义啊...

64,642

社区成员

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

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