传递接受 void * 的成员函数

Passing member function that accepts void *

本文关键字:成员 函数 void      更新时间:2023-10-16

我正在处理需要将成员函数指针发送到接受 void * 作为参数的记录器方法的代码。 我无法从无效*更改它。 我也不能使用 c++11。 有没有办法让它在没有任何警告的情况下工作。 例如:

logger.h

    #ifndef _LOGGER_H
    #define _LOGGER_H
    void logger( void *func );
    #endif /* _LOGGER_H */

记录器.cpp

    #include <cstdio>
    #include "logger.h"
    void logger( void *func )
    {
        printf("%lxn", (unsigned long)func);
    }

测试用例.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 来说却是不同的。

你能想到另一种方法来让它工作吗?

引用

不,你不能让它发生。标准禁止将指向成员的指针转换为void*。原因是它们与void*不兼容 - 它们通常是void*的两倍大小.

您的代码还有其他问题,例如,(unsigned long)funcvoid*转换为无符号长整型,这也是未定义的。例如,在许多系统上,long 的长度为 32 位,而 void* 的长度为 64 位。若要可靠地将void*转换为整数类型,需要使用uintptr_t(前提是您的实现具有它)。

我不知道

"两倍大小"; 指针就是指针,在我的理解中,给定系统上的所有指针大小都相同,无论它们指向什么......

然而,看看我那本Stroustrup的《C++编程语言,第3版》(第101页):

应怀疑系统较高杠杆处发生void*s的情况,因为它们可能是设计错误的指标。 在用于优化的情况下,void*可以隐藏在类型安全接口后面(§13.5、§24.4.2)。

指向函数的指针 (§7.7) 和指向成员的指针 (§15.5) 不能分配给void*s