当前位置: 首页 > 知识库问答 >
问题:

如何在boostpython中公开使用变量参数的c函数

夹谷弘亮
2023-03-14

我有一个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\u 1\u 42\u 0/boost/python/data\u成员提供的文件中。hpp:15,from/boost\u 1\u 42\u 0/boost/python/class。hpp:17,来自/boost\u 1\u 42\u 0/boost/python。水电站:18,来自Lib_boost。h:3,来自Lib_boost。cpp:1:/boost\u 1\u 42\u 0/boost/python/make\u函数。hpp:在函数“boost::python::api::object boost::python::make_function(F)[with F=const char*()(int,…)]中:/boost_1_42_0/boost/python/def。hpp:82:
从'boost::python::api::object boost::python::detail::make_function1(T,…)实例化[带T=const char()(int,…)]/boost_1_42_0/boost/python/def。hpp:91:从“void boost::python::def(const char,Fn)[其中Fn=const char*()(int,…)]实例化自助餐。cpp:540:从这里实例化/boost\u 1\u 42\u 0/boost/python/make\u函数。hpp:104:错误:从“const char()(int,…)”的转换无效到'const char()(int)/boost\u 1\u 42\u 0/boost/python/make\u函数。hpp:104:错误:
初始化“boost::mpl::vector2 boost::python::detail::get_签名(RT()(T0),void*)[带有RT=const char*,T0=int]的参数1”

根据上面的错误信息,我的理解是boostpython无法识别使用变量参数的函数(从“constchar*()(int,…)”转换无效)至“常量字符(*)(int)”)

公开具有固定/已知参数集的函数与使用变量参数的函数不同。如何公开具有可变参数的函数?

共有3个答案

温浩大
2023-03-14

只要知道最大计数可以是多少,就可以将参数视为可选参数。请看这里:https://wiki.python.org/moin/boost.python/FunctionOverloading

浦德义
2023-03-14

如果您使用的是C11,那么以下内容可能会起作用(在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,…)”简单地连接所有字符串参数并返回结果字符串。

郗鹏
2023-03-14

我发现处理变量参数的最好方法是使用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_函数接受两个参数:函数指针和最小参数数。

 类似资料:
  • 具有以下示例JNLP: (请忽略格式或其他不一致的地方--唯一重要的部分是参数部分) 如果变量db_port位于argument标记中,那么在使用JavaWS执行jnlp时,是否有方法将值传递给该变量? 例如:javaws/path/to/sample.jnlp 31022 编辑: JNLP将JAR下载到位于AppData\locallo\sun\java\deployment\cache下的缓存

  • 本文向大家介绍实例讲解在C++的函数中变量参数及默认参数的使用,包括了实例讲解在C++的函数中变量参数及默认参数的使用的使用技巧和注意事项,需要的朋友参考一下 包含变量参数列表的函数 如果函数声明中最后一个成员是省略号 (...),则函数声明可采用数量可变的参数。在这些情况下,C++ 只为显式声明的参数提供类型检查。即使参数的数量和类型是可变的,在需要使函数泛化时也可使用变量参数列表。函数的系列是

  • 问题内容: 如何在python函数中设置全局变量? 问题答案: 要在函数内部使用变量,您需要像这样在函数内部进行操作。 给出输出 请记住,如果您要进行分配/更改它们,则只需要在函数内声明它们。打印和访问不需要。 你可以做, 而不像我们在第一个函数中那样声明它,它仍然可以正确赋值。 以a为例,您不能在不声明的情况下分配a ,但是可以调用它的方法并更改列表。如下所示。

  • 问题内容: 我正在为我的应用程序创建搜索表单。 用户在其中选择应该用于过滤数据的字段。 数字字段是可变的,所以我不知道SQL查询的where子句中应该有多少个。 如何在where子句中使用可变数量的条件? 谢谢 问题答案: PrepardStatements不支持可变数量的条件。一些框架所做的是将每个PreparedStatement缓存在Map中,键是查询。 因此,每次您要运行查询时,都需要构建

  • 问题内容: 如何在try / except块内将变量设为公共? 此代码返回错误 NameError:名称“文本”未定义 如何在try / except块之外使变量文本可用? 问题答案: 语句不会创建新的作用域,但是如果调用引发异常,则不会设置该语句。您可能希望在子句中使用该行,以便仅在没有异常的情况下才执行该行。 如果以后需要使用,您真的需要考虑如果分配失败并且您无法致电,其值应该是什么。您可以在

  • 本文向大家介绍Swift如何调用Objective-C的可变参数函数详解,包括了Swift如何调用Objective-C的可变参数函数详解的使用技巧和注意事项,需要的朋友参考一下 前言 这个问题是一个朋友问我怎么写,一开始我是拒绝的。我想这种东西网上随便 google 下不就有了吗。他说,查了,但没大看明白。于是我就查了下,没想到这个写法确实有点诡异,我第一反应也没看明白。所以随便水一篇文章,强行

  • 问题内容: 似乎不符合我的想法。有什么建议? 问题答案: (模糊的问题) 您是否以错误的方式获取了Category和@Variable:sqlFiddle

  • 问题内容: 我有一个看起来像的文件夹结构: : : : : : : 当我直接使用该模块时,它似乎按预期工作: 但是,当我在sphinx中使用自动模块时(将项目文件夹添加到sys.path之后): 我得到的页面只有: 似乎正在忽略类型语句。 但是,如果我将所有代码直接复制到每个模块/子模块的文件中,则会得到: sphinx是否不适用于文件中具有此类导入语句的模块,还是我遗漏了一个更明显的问题? 理想