Search code examples
macoscallbacktext-to-speechmacos-carbon

Callback function with carbon API


I'm trying to install a callback function with a carbon API but it doesn't work: it is triggered correctly by the event (when it finishes speaking) but it returns a segmentation fault 11 instead of printing "...Finished.".

Here's the code:

...
/* Creates SpeechChannel */
SpeechChannel speechchannel;
NewSpeechChannel(NULL,&speechchannel);


/* Sets callback */
CFNumberRef cbf = CFNumberCreate (
                            NULL,
                            kCFNumberLongType,
                            MySpeechDoneProc
                            );
OSErr error1;
error1 = SetSpeechProperty (speechchannel,kSpeechSpeechDoneCallBack,cbf);


/* Speaks it */
OSErr error2;
error2 = SpeakCFString(speechchannel, finalString, NULL);
...

later there is:

void MySpeechDoneProc (SpeechChannel chan,long refCon)
{
printf("...Finished.");
};

I guess I'm not installing the callback function properly?


Solution

  • The problem was that I didn't use the pointer to callback function in the creation of the CFNumberRef. The solution is twofold:

    1) Declare the pointer for the function along with the function:

    /* callback function */
    void MySpeechDoneProc (SpeechChannel chan,long refCon);
    /* callback function pointer */
    void (*MySpeechDoneProcPtr)(SpeechChannel,long);
    

    2) Pass the address of the callback function pointer as third argument in CFNumberCreate:

    error1 = SetSpeechProperty (speechchannel,kSpeechSpeechDoneCallBack,cbf);
    

    Here is the working code:

    ...
    /* Creates SpeechChannel */
    SpeechChannel speechchannel;
    NewSpeechChannel(NULL,&speechchannel);
    
    
    /* Sets callback */
    MySpeechDoneProcPtr = &MySpeechDoneProc;
    CFNumberRef cbf = CFNumberCreate (
                                NULL,
                                kCFNumberLongType,
                                &MySpeechDoneProcPtr
                                );
    OSErr error1;
    error1 = SetSpeechProperty (speechchannel,kSpeechSpeechDoneCallBack,cbf);
    
    
    /* Speaks it */
    OSErr error2;
    printf("Speaking...\n");
    error2 = SpeakCFString(speechchannel, finalString, NULL);
    ...