7

我需要用 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;
    };

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

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

这行得通吗?没有办法定义新的 C 回调?

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

4

1 回答 1

2

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

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

于 2012-12-18T14:28:54.983 回答