用于包装类方法的回调函数和static_cast

callback functions and static_cast for wrapping class methods

本文关键字:static cast 函数 回调 包装 包装类 类方法 用于      更新时间:2023-10-16

我有一些麻烦,使回调包装类方法需要由第三方库使用;

我已经能够为JackAudio回调函数制作一个包装器,它需要两个参数。

我只是在为需要const char *作为参数的特定函数创建回调函数时遇到了麻烦。

到目前为止,我已经能够使JackAudio库jack_set_sample_rate_callback函数使用自定义类,并且可以像这样执行:

SoundClass Sound;
SoundClass * SoundPointer = &Sound;
jack_set_sample_rate_callback( 
                              client, 
                              SoundClass::SampleRateCallbackWrapper, 
                              SoundPointer 
                             );

类看起来像这样:

SoundClass
{
int SampleRateCallback( jack_nframes_t nframes )
    {
        //executes some code when called.
    }
 static int SampleRateCallbackWrapper( jack_nframes_t nframes, void * arg )
    {
        return static_cast < SoundClass* > ( arg )->SampleRateCallback( nframes );
    }
};

以上都运行良好,没有任何问题。

我现在遇到的问题是与JackAudio回调函数jack_set_error_function

这是我尝试过的:

static void  ErrorCallbackWrapper( const char * arg  )
{
    return static_cast < SoundClass*>( arg )->SomeErrorFunction();
}

得到error: invalid static_cast from type ‘const char*’ to type ‘SoundClass*’

我知道为什么会发生这种情况,我只是不知道该怎么解决。

谢谢大家的帮助。

假设Jack API是为C语言编写的,那么您拥有的工作回调已经存在一个正式的问题。也就是说,它需要是extern "C",而作为一个静态成员函数,它不能是。所以形式上它需要是一个独立的函数。

您链接到的jack_set_error_function的文档给出了这个签名,大概用C表示:

void jack_set_error_function( void(*)(const char *) func);

对于c++,回调必须假定为extern "C",因此,

extern "C" void MyErrorFunction( char const* errorMessage )
{
    // Whatever, e.g. post a message to the GUI event queue, or terminate.
}

如果你想让这个函数反过来调用对象上的一个方法,那么除非标准库提供了一些特殊的机制来帮助你,否则你将不得不使用以下技术之一:

  • 一个被回调访问的命名空间作用域变量,或者

  • 动态生成的回调。

c++目前根本不支持第二种方法,因此第一种方法被强烈标识为& &;如果你想对一个对象的方法进行回调。


EDIT:对不起,我忘了说,

        API文档中的函数声明在语法上无效

。文档签名

void jack_set_info_function( void(*)(const char *) func );

不能使用符合标准的编译器进行编译。不像C,也不像c++。在两种语言中语法都无效。

应该是

void jack_set_info_function( void(*func)(const char *) );

由于文档显然是由氧生成的,因此它是由编译的源代码生成的。如果是这样,那么这就是oxygen中的一个bug,并且是库提供者的质量保证问题。然而,这可能是一个问题,仅仅在于库提供程序,或者,我可能错误地假设这是一个C库?