使用C++回调编写C++类的C包装器

jen*_*sph 7 c c++ callback wrapper

我需要用C包装一个C++库.这个C++库定义了回调函数.例如:

    // from C++ library

    typedef X CallbackFn(Y y); // X and Y are classes

    class Z
    {
    public:
            void addCallback( CallbackFn* fn ) { callbackFn = fn; }
    private:
            CallbackFn* callbackFn;
    };
Run Code Online (Sandbox Code Playgroud)

在C包装器中,我可以定义新的C回调,它调用C++回调.像这样的东西:

    // in C wrapper

    extern "C" {

    typedef int CallbackFnC(int n, ... );

    CallbackFnC *callbackFnC;

    int addCallback(void* handle, CallbackFnC* fn) // handle is pointer to Z instance
    {
        callbackFnC = fn;
        ((Z*)handle)->addCallback(callbackFnCPP);
    }

    }

    X callbackFnCPP(Y y)
    {
        int rtn = callbackFnC(y.n, ...);
        return X(rtn);
    }
Run Code Online (Sandbox Code Playgroud)

我假设我可以将Y的相关成员映射到C回调函数的参数,并且我可以从C返回充分构造返回类型X.

这会起作用吗?没有办法定义新的C回调?

新的C回调应该在内部,extern "C"并且C++回调的定义实例应该在外面?

Bar*_*nau 2

是的,用 C 回调和 C++ 包装函数替换 C++ 回调将起作用(有一些注意事项),不,如果 C++ 回调坚持传递/返回类或引用(与 C 也支持的基本类型相反),那么包装方法是唯一可能的解决方案。

使用包装函数的主要注意事项是包装函数需要某种方法来找到要调用的正确 C 函数。使用全局是一种简单的解决方案,但现在整个程序仅限于一个回调(无论您拥有多少个 Z 对象)。更灵活的解决方案将取决于 C++ 回调的设计,范围从简单(注册时,您可以提供将提供给回调的任意用户数据)到非常困难。