python 指针数组_python – 通过SWIG传递函数指针数组

https://stackoverflow.com/a/22965961/353337的帮助下,我能够创建一个如何通过Python将一个函数指针传递给函数的简单示例.具体来说,有

double f(double x) {

return x*x;

}

double myfun(double (*f)(double x)) {

fprintf(stdout, "%g\n", f(2.0));

return -1.0;

}

%module test

%{

#include "test.hpp"

%}

%pythoncallback;

double f(double);

%nopythoncallback;

%ignore f;

%include "test.hpp"

我可以打电话

import test

test.f(13)

test.myfun(test.f)

并获得预期的结果.

现在,我想更改myfun的签名以允许一组函数指针(都具有相同的签名),例如,

double myfun(std::vector)

我如何修改.i文件?

理想情况下,Python调用将通过列表

test.myfun([test.f, test.g])

最佳答案 我做了以下测试用例来说明你正在尝试做什么.它有一个真实的myfun实现(const std :: vector< double(*)(double)>&),让生活变得更有趣:

#include

double g(double x) {

return -x;

}

double f(double x) {

return x*x;

}

typedef double(*pfn_t)(double);

std::vector myfun(const std::vector& funs, const double d) {

std::vector ret;

ret.reserve(funs.size());

for(auto && fn : funs)

ret.emplace_back(fn(d));

return ret;

}

我希望我们需要做的就是使用以下功能:

%include

%template(FunVec) std::vector;

%template(DoubleVec) std::vector;

%include "test.h"

但是,SWIG 3.0(来自Debian stable)无法正确处理此FunVec,并且生成的模块无法编译.所以我添加了一个typemap作为变通方法:

%module test

%{

#include "test.h"

%}

%pythoncallback;

double f(double);

double g(double);

%nopythoncallback;

%ignore f;

%ignore g;

%typemap(in) const std::vector& (std::vector tmp) {

// Adapted from: https://docs.python.org/2/c-api/iter.html

PyObject *iterator = PyObject_GetIter($input);

PyObject *item;

if (iterator == NULL) {

assert(iterator);

SWIG_fail; // Do this properly

}

while ((item = PyIter_Next(iterator))) {

pfn_t f;

const int res = SWIG_ConvertFunctionPtr(item, (void**)(&f), $descriptor(double(*)(double)));

if (!SWIG_IsOK(res)) {

assert(false);

SWIG_exception_fail(SWIG_ArgError(res), "in method '" "foobar" "', argument " "1"" of type '" "pfn_t""'");

}

Py_DECREF(item);

tmp.push_back(f);

}

Py_DECREF(iterator);

$1 = &tmp;

}

%include

// Doesn't work:

//%template(FunVec) std::vector;

%template(DoubleVec) std::vector;

%include "test.h"

基本上所有这一切都是为函数指针类型的向量添加一个’in’类型映射.该类型映射只是迭代Python提供的输入,并从Python iterable构建一个临时的std :: vector.

这足以使以下Python按预期工作:

import test

print test.g

print test.f

print test.g(666)

print test.f(666)

print test.myfun([test.g,test.f],123)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值