سؤال

I'm having some trouble making a callback wrapper class method that needs to be used by a third party library; the JackAudio library.

I have been able to make a wrapper for a JackAudio callback function that needs two arguments.

I'm just having trouble creating a callback function for a particular function that needs a const char * as an argument.

So far I have been able to make the JackAudio library jack_set_sample_rate_callback function use a custom class and can be executed like so:

SoundClass Sound;

SoundClass * SoundPointer = &Sound;

jack_set_sample_rate_callback( 
                              client, 
                              SoundClass::SampleRateCallbackWrapper, 
                              SoundPointer 
                             );

And the class looks something like this:

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 );
    }
};

All of the above works well, with no issues.

The problem I'm having now is with the JackAudio callback function jack_set_error_function

This is what I tried:

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

But I get error: invalid static_cast from type ‘const char*’ to type ‘SoundClass*’

I get the gist why this is happening, I just have no idea what to do for a solution.

Thanks in advance for any help guys.

هل كانت مفيدة؟

المحلول

Assuming the Jack API is written for the C language, there is a formal problem already with the working callback that you have. Namely that it then needs to be extern "C", and that as a static member function it cannot be. So formally it needs to be a free-standing function.

The documentation that you link to for the jack_set_error_function gives this signature, presumably expressed in C:

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

For C++ the callback must be assumed to be extern "C", so,

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

If you want this function to in turn call a method on an object, then unless the library provides some special mechanism to help you, you will just have to use one of the following techniques:

  • a namespace scope variable accessed by the callback, or

  • a dynamically generated callback.

C++ does not as of yet support the second approach, at all, so the first one is strongly indicated – if you want a callback on a method of an object.


EDIT: Sorry, I forgot to mention,

        the function declarations in the API documentation are syntactically invalid.

E.g. the documentation’s signature

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

simply won’t compile with a standard-conforming compiler. Not as C, and not as C++. It’s syntactically invalid in both languages.

Instead it should be

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

Since the documentation apparently is generated by DOxygen, it stands to reason that it's been generated from source code that compiles. If so then this is a bug in DOxygen, and a problem with the quality assurance of the library provider. However it might be a problem that lies solely with the library provider, or, I might be mistaken in the assumption that this is a C library?

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top