如何暴露一个c ++函数接受可变参数在boost python [英] How to expose a c++ function taking variable arguments in boost python

查看:252
本文介绍了如何暴露一个c ++函数接受可变参数在boost python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个c ++函数采用可变数量的参数。

I have a c++ function taking variable number of arguments.

   char const* Fun(int num, ...)
   {
   ....//does some processing on the arguments passed
   }

Boost暴露此函数的Python代码是写为,

Boost Python code for exposing this function is written as,

    using namespace boost::python;
    BOOST_PYTHON_MODULE( lib_boost )
   {
       def( "Fun", Fun );
   }

而编译此代码时会出现以下错误

while compiling this code gives the below error


在/boost_1_42_0/boost/python/data_members.hpp:15中包含的文件中,
来自/boost_1_42_0/boost/python/class.hpp:17,
从/boost_1_42_0/boost/python.hpp:18,
从Lib_boost.h:3,
从Lib_boost.cpp:1:/boost_1_42_0/boost/python/make_function.hpp:在函数
'boost :: python :: api :: object boost :: python :: make_function(F)[F =
const char *()(int,...) :/boost_1_42_0/boost/python/def.hpp:82:

从'boost :: python :: api :: object
实例化boost :: python :: detail :: make_function1(T ,...)[with T = const char

)(int,...)]'/boost_1_42_0/boost/python/def.hpp:91:instantiated
from'void boost :: python :: def(const char
,Fn)[with Fn = const char *
(em,...)]'Lib_boost.cpp: 540:从此处实例化
/boost_1_42_0/boost/python/make_function.hpp:104:错误:无效
从const char ()(int,...) 'to'const char
)(int)/boost_1_42_0/boost/python/make_function.hpp:104:错误:

初始化'boost: :mpl :: vector2
boost :: python :: detail :: get_signature(RT(
)(T0),void *)[with RT =
const char *,T0 = int] '

In file included from /boost_1_42_0/boost/python/data_members.hpp:15, from /boost_1_42_0/boost/python/class.hpp:17, from /boost_1_42_0/boost/python.hpp:18, from Lib_boost.h:3, from Lib_boost.cpp:1: /boost_1_42_0/boost/python/make_function.hpp: In function 'boost::python::api::object boost::python::make_function(F) [with F = const char* ()(int, ...)]': /boost_1_42_0/boost/python/def.hpp:82:
instantiated from 'boost::python::api::object boost::python::detail::make_function1(T, ...) [with T = const char
()(int, ...)]' /boost_1_42_0/boost/python/def.hpp:91: instantiated from 'void boost::python::def(const char, Fn) [with Fn = const char* ()(int, ...)]' Lib_boost.cpp:540: instantiated from here /boost_1_42_0/boost/python/make_function.hpp:104: error: invalid conversion from 'const char ()(int, ...)' to 'const char ()(int) /boost_1_42_0/boost/python/make_function.hpp:104: error:
initializing argument 1 of 'boost::mpl::vector2 boost::python::detail::get_signature(RT (
)(T0), void*) [with RT = const char*, T0 = int]'

我从上面的错误信息的理解是boost python不能识别函数接受变量参数()(int,...)'to'const char (*)(int)')

My understanding from the error info above is boost python could not recognize the function taking variable arguments(invalid conversion from 'const char* ()(int, ...)' to 'const char (*)(int)')

已知的参数集对于采用可变参数的函数是不相同的。
如何使用可变参数显示函数?

Exposing a function with fixed/known set of arguments is not the same for functions taking variable arguments. How to expose a function with variable arguments?

推荐答案

如果你使用c ++ 11, (在g ++ - 4.8.2上测试)

if you are using c++11 then following could work ( tested on g++-4.8.2 )

#include <boost/python.hpp>
#include <boost/python/list.hpp>
#include <vector>
#include <string>
#include <cstdarg>
#include <cassert>

using namespace boost::python;

template <int... Indices>
struct indices
{
    using next = indices<Indices..., sizeof...(Indices)>;
};

template <int N>
struct build_indices
{
    using type = typename build_indices<N-1>::type::next;
};

template <>
struct build_indices<0>
{
    using type = indices<>;
};
template <int N>
using BuildIndices = typename build_indices<N>::type;

template <int num_args>
class unpack_caller
{
private:
    template <typename FuncType, int... I>
    char * call(FuncType &f, std::vector<char*> &args, indices<I...>)
    {
        return f(args.size(), args[I]...);
    }

public:
    template <typename FuncType>
    char * operator () (FuncType &f, std::vector<char*> &args)
    {
        assert( args.size() <= num_args );
        return call(f, args, BuildIndices<num_args>{});
    }
};

//This is your function that you wish to call from python
char * my_func( int a, ... )
{
    //do something ( this is just a sample )
    static std::string ret;

    va_list ap;
    va_start (ap, a);
    for( int i = 0; i < a; ++i)
    {
        ret += std::string( va_arg (ap, char * ) );
    }

    va_end (ap);
    return (char *)ret.c_str();
}

std::string my_func_overload( list & l )
{
    extract<int> str_count( l[0] );
    if( str_count.check() )
    {
        int count = str_count();
        std::vector< char * > vec;
        for( int index = 1; index <= count; ++index )
        {
            extract< char * > str( l[index] );
            if( str.check() )
            {
                //extract items from list and build vector
                vec.push_back( str() );
            }
        }
        //maximum 20 arguments will be processed.
        unpack_caller<20> caller;

        return std::string( caller( my_func, vec ) );
    }

    return std::string("");
}

BOOST_PYTHON_MODULE(my_module)
{
    def("my_func", my_func_overload )
    ;
}

在python中:

Python 2.7.6 (default, Mar 22 2014, 22:59:38) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_module as m
>>> m.my_func([5, "my", " first", " five", " string", " arguments"])
'my first five string arguments'
>>>

在此示例中,char * my_func(int a,...)简单地连接所有字符串参数并返回结果字符串。

In this example "char * my_func( int a, ... )" simply concatenates all the string arguments and returns the resulting string.

这篇关于如何暴露一个c ++函数接受可变参数在boost python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆