How to generate wrappings for C++ functions?

杀马特。学长 韩版系。学妹 提交于 2019-12-24 07:38:10

问题


I'm trying to create a generic way to wrap C++ functions (from a different language). I have a list of parameters (and and an iterator) and a specific C++ function to be called on the list of parameters. I'm trying to find someway to unpack the list of parameters as arguments to my function.

My current approach is to:

  1. Use Boost::FunctionTypes to get the parameters of the function as a sequence.
  2. Create a Boost::Fusion list that would contain the values of the arguments, using the values of the parameter types for casting.
  3. Call the function with the created list using boost::fusion's invoke.

Both the steps (1) and (2) seem fairly straightforward to do. However, I can't figure out how to do the second step (or if it's even possible -- mixing compile-time and run-time seems a little strange).

Does anyone have any idea of how to either do the second step, or a better approach on this problem?

I know Boost::Python has to do something similar, but the code is a little dense to get a good sense of what is happening.

update

I have a partial solution, which works for (at least) simple cases. There's still problems with dealing with reference.

Hopefully someone can post something better solution.

The list contains pointers to a base class A, from which all other classes used are derived. I have two subclasses B and C which contain different value types (int and string).

The operator convert takes the given class and gets the underlying value. These values are collected by transform into a sequence which is then given to invoke.

class A {
public:
    A() {}
    virtual ~A() {} 
};

class B: public A {
protected:
    int value;
public:
    B() {}  
    B(int v): value(v) {}

    int getValue() { return value; }
};

class C: public A {
protected:
   string value;
public:
    C() {}  
    C(const string &v): value(v) {}

    string &getValue() { return value; }
};


// this pattern was copied from the test files from the fusion library
struct convert {
    // keep a reference to the parameter we're going to unpack
    list<A *>::iterator &param;

    convert(list<A *>::iterator &param): param(param) {}

    template<typename Sig>
    struct result;

    template <typename T>
    struct result<convert(T)> {
        typedef T type;
    };

    // this must be specialized in order to properly deal with the return types
    template <typename T>
    T operator ()(T type) const {}  
};

template <>
int convert::operator ()(int type) const {
    B *b = dynamic_cast<B *>(*param++);
    if (b != NULL) return b->getValue();
    throw error("illegal cast");
}

template <>
string convert::operator ()(string type) const {
    C *c = dynamic_cast<C *>(*param++);
    if (c != NULL) return c->getValue();
    throw error("illegal cast");
}

and finally, to call a function:

// create a parameter list (usually this would be passed to us)
list<A *> params;
params.push_back(new B(2));
params.push_back(new C("test"));

// point to beginning of parameter
list<A *>::iterator pos = params.begin();


// foo is the function we're going to call,
typedef BOOST_TYPEOF(foo) params_type;

// use the parameter list of foo to unpack the parameter list
auto passedParams = fusion::as_list(fusion::transform(function_types::parameter_types<params_type>(), trans(pos)));

// finally, call foo with the sequence that was created by the transform
fusion::invoke(foo, passedParams);

来源:https://stackoverflow.com/questions/11164914/how-to-generate-wrappings-for-c-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!