简体   繁体   中英

How to modify C++ class member variables from C callback

My goal is changing the Width and Height in TTerm .

#include <iostream>

extern "C" 
{
    void SomeCFunctionThatRequireCallback(void (*FuncPtr)(int Width, int Height))
    {
        FuncPtr(80, 20);
    }
}

class TTerm
{
public:
    int IO;
    int WinchFds[2];

    int Width;
    int Height;

    TTerm()
    {
        SomeCFunctionThatRequireCallback(OnResizeCallback);
    }

    static void OnResizeCallback(int Width, int Height)
    {
        // Set this->Width and this->Height
    }
};

int main() 
{
    TTerm Term;
}

If the C callback is yours or you can change it, you may pass a pointer to the class instance and call some member function in the static method:

extern "C" 
{
    void SomeCFunctionThatRequireCallback(void * ptr, void (*FuncPtr)(void *, int, int))
    {
        FuncPtr(ptr, 80, 20);
    }
}

    TTerm()
    {
        SomeCFunctionThatRequireCallback(this, OnResizeCallback);
    }

    static void OnResizeCallback(void * ptr, int Width, int Height)
    {
        // Set this->Width and this->Height
        TTerm * instance = (TTerm*)ptr;
        instance->Width = Width;
        instance->Heght = Height;
    }

You could pass the ints as references also. But, again, you need to modify the callback signature.

If you can't change the callback signature, you have to keep control of who calls the callback and do something in the static method.

You could protect the callback with a semaphore in another class and get the needed data from there.

(Non compiling example.)

TTerm() {
    SomeCFunctionObject & obj = SomeCFunctionObject.getInstance();
    obj.setCaller (this);
    obj.doCallback ();
    Width = obj._width;
    Height = obj._height;
}

class SomeCFunctionObject {
public:
    int _width;
    int _height;

    static SomeCFunctionObject & getInstance () {
        static SomeCFunctionObject obj;
        return obj;
    }

    static void OnResizeCallback(int Width, int Height)
    {
        SomeCFunctionObject & obj = SomeCFunctionObject.getInstance();
        obj._width = Width;
        obj._height = Height;
        // free semaphore
    }    
    void setCaller (void * using) {
        // get semaphore
        _using = using
    }

    void doCallback () {
        SomeCFunctionThatRequireCallback(OnResizeCallback);
    }

private:
    void * _using;

    SomeCFunctionObject () {}

};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM