传递接受void *

时间:2016-03-16 14:16:51

标签: c++ pointers parameters casting member

我正在处理需要将成员函数指针发送到接受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不同。

你能想到另一种方法让它发挥作用。

References

2 个答案:

答案 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