如何在boost python中公开一个接受变量参数的c++函数
How to expose a c++ function taking variable arguments in boost python
我有一个接受可变数量参数的c++函数。
char const* Fun(int num, ...)
{
....//does some processing on the arguments passed
}
Boost Python中暴露这个函数的代码如下:
using namespace boost::python;
BOOST_PYTHON_MODULE( lib_boost )
{
def( "Fun", Fun );
}
在编译这段代码时会产生以下错误
从/boost_1_42_0/boost/python/data_members.hpp:15,从/boost_1_42_0/提高/python/class.hpp: 17日从/boost_1_42_0/提高/python.hpp: 18日从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/提高/python/def.hpp: 82:
由` boost::python::api::object `实例化boost::python::detail::make_function1(T,…)[with T = const char]() (int , ...)]'/boost_1_42_0/提高/python/def.hpp: 91:实例化from ` void boost::python::def(const char, Fn) [with Fn = const char* . .()(int,…)]' Lib_boost.cpp:540:从这里实例化/boost_1_42_0/boost/python/make_function.hpp:104: error: invalid从'const char ()(int,…)'到'const char的转换()(int)/boost_1_42_0/boost/python/make_function.hpp:104: error:
初始化boost::mpl::vector2的参数1boost::python::detail::get_signature(RT ()(T0), void*) [with RT =const char*, T0 = int]'
我对上面错误信息的理解是boost python无法识别接受变量参数的函数(从'const char* ()(int,…)'到'const char (*)(int)'的无效转换)
使用固定/已知参数集公开函数与使用可变参数的函数不同。如何暴露一个函数与变量参数?
我发现处理可变参数的最好方法是使用raw_function
。通过这种方式,您可以完全控制将c++参数转换为Python对象:
包装:
using namespace boost::python;
object fun(tuple args, dict kwargs)
{
char* returned_value;
for(int i = 0; i < len(args); ++i) {
// Extract the args[i] into a C++ variable,
// build up your argument list
}
// build your parameter list from args and kwargs
// and pass it to your variadic c++ function
return str(returned_value);
}
声明:
def("fun", raw_function(fun, 1) );
raw_function
接受两个参数:函数指针和最小参数数。
如果您使用的是c++11,那么以下操作可以工作(在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,…)简单地连接所有字符串参数并返回结果字符串。
您可以通过将参数视为可选来实现,只要您知道最大计数可以是多少。详见:https://wiki.python.org/moin/boost.python/FunctionOverloading
- 用C++中的一个变量定义一个常量
- 一个变量的输入值也会保存到另一个变量中
- 将双精度变量设置为另一个变量的值
- 对具有相同方法的不同类使用一个变量
- 为什么一个变量获得与另一个值相同的值
- 尝试在 C++ 中为 ifstream 提供一个变量
- 类中的一个变量显示,但另一个不显示
- 声明一个变量,该变量在 c++ 或 c 中具有值,当程序终止时不会被销毁
- c++问题:给一个变量赋值后,另一个变量发生了变化
- 如何将一个变量用于父类和派生类
- 如何在循环中使用scanf,将值存储到一个变量中,然后打印出来?
- 我如何将一个变量与另一个变量进行比较,例如我想如果(var1 > var2 x 1),然后执行此 c++
- 如何在一个函数中定义一个变量,并在另一个函数中访问和更改它?(C++)
- 如果一个变量在它之前释放了另一个(相同的数据类型)变量,如何将其分配给内存?
- 迭代器或反向器的一个变量
- fstream库,试图创建一个变量名为(c++)的文件
- 如何在 c++ 中将两个不同类型的变量分配给一个变量
- 如何将一些变量放在一个变量中?
- 将 int 转换为字符串,然后连接另一个变量以创建完整扩展名,然后将其转换为 const_char*
- 如何用索引命名一个变量来存储输入 mxArray?