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

时间:2012-12-24 02:49:28

标签: c++ static-cast

我在制作需要第三方库使用的回调包装类方法时遇到了一些麻烦; JackAudio library

我已经能够为需要两个参数的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*’

我明白为什么会发生这种情况,我只是不知道如何解决问题。

提前感谢任何帮助人员。

1 个答案:

答案 0 :(得分:2)

假设Jack API是为C语言编写的,那么您的工作回调已经存在正式问题。即它然后需要extern "C",并且作为静态成员函数它不能。所以正式地说它需要是一个独立的功能。

您为jack_set_error_function链接的documentation会给出此签名,大概用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 ++还没有支持第二种方法,所以第一种方法是强烈指示的 - if 你想要对对象的方法进行回调。


编辑:抱歉,我忘了提及,

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

E.g。文档的签名

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

根本不会使用符合标准的编译器进行编译。不是C,而不是C ++。它在两种语言中在语法上都是无效的。

相反它应该是

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

由于文档显然是由DOxygen生成的,因此可以理解它是由编译的源代码生成的。如果是这样,那么这是DOxygen中的一个错误,也是图书馆提供商质量保证的问题。然而,它可能只是一个问题,只有图书馆提供者,或者,我可能会误认为这是一个C库?