我正在处理需要将成员函数指针发送到接受void *作为参数的记录器方法的代码。我无法从void *改变它。我也不能使用c ++ 11。有没有办法让它在没有任何警告的情况下工作。例如:
logger.h
#ifndef _LOGGER_H
#define _LOGGER_H
void logger( void *func );
#endif /* _LOGGER_H */
logger.cpp
#include <cstdio>
#include "logger.h"
void logger( void *func )
{
printf("%lx\n", (unsigned long)func);
}
testCase.cpp
#include "logger.h"
class myClass
{
public:
void testCase( void );
};
void myClass::testCase( void )
{
/* This works on my compiler, but gives warning */
/* warning: converting from 'void (myClass::*)()' to 'void*' */
/* I know this is bad and wrong. */
logger((void *)&myClass::testCase);
/* This compiles without warning */
/* But doesnt work the way I need, gives ffff*/
void (myClass::*ptr)( void ) = &myClass::testCase;
void *m_ptr = ptr;
logger(m_ptr);
}
logger.h和logger.cpp无法更改。
这是运行VxWorks,我需要在符号表中查找地址。当我尝试第二种方式时,我得到了ffff。虽然在使用其他编译器时我得到了一个真实的地址,但它与VxWorks不同。
你能想到另一种方法让它发挥作用。
答案 0 :(得分:3)
不,你无法实现。标准禁止将指针转换为成员void*
。原因是它们与void*
不兼容 - 它们的大小通常是void*
的两倍。
您的代码也有其他问题,例如,(unsigned long)func
正在将void*
转换为无符号长整数,这也是未定义的。例如,在许多系统上,长度为32位,而void*
为64位。要将void*
可靠地转换为整数类型,您需要使用uintptr_t
(假设您的实现具有它)。
答案 1 :(得分:1)
我不知道“双倍大小”;指针是指针,在我的理解中,给定系统上的所有指针都是相同的大小,无论它们指向什么......
但是,查看Stroustrup的第3版“C ++编程语言”(第101页):
系统较高杠杆的
void*s
发生的事件应该被怀疑,因为它们可能是设计错误的指标。在用于优化的地方,void*
可以隐藏在类型安全接口(第13.5节,第24.4.2节)之后。无法将指向函数的指针(第7.7节)和指向成员的指针(第15.5节)分配给
void*s
。