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 testtest.f(13)test.myfun(test.f)
并获得预期的结果.
现在,我想更改myfun的签名以允许一组函数指针(都具有相同的签名),例如,
double myfun(std::vector<double (*)(double)>)
我如何修改.i文件?
理想情况下,Python调用将通过列表
test.myfun([test.f,test.g])解决方法 我做了以下测试用例来说明你正在尝试做什么.它有一个真实的myfun实现(const std :: vector< double(*)(double)>&),让生活变得更有趣:
#include <vector>double g(double x) { return -x;}double f(double x) { return x*x;}typedef double(*pfn_t)(double);std::vector<double> myfun(const std::vector<pfn_t>& funs,const double d) { std::vector<double> ret; ret.reserve(funs.size()); for(auto && fn : funs) ret.emplace_back(fn(d)); return ret;}
我希望我们需要做的就是使用以下功能:
%include <std_vector.i>%template(FunVec) std::vector<double(*)(double)>;%template(Doublevec) std::vector<double>;%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<pfn_t>& (std::vector<pfn_t> 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); = &tmp;}%include <std_vector.i>// Doesn't work://%template(FunVec) std::vector<double(*)(double)>;%template(Doublevec) std::vector<double>;%include "test.h"
基本上所有这一切都是为函数指针类型的向量添加一个’in’类型映射.该类型映射只是迭代Python提供的输入,并从Python iterable构建一个临时的std :: vector.
这足以使以下Python按预期工作:
import testprint test.gprint test.fprint test.g(666)print test.f(666)print test.myfun([test.g,test.f],123)总结
以上是内存溢出为你收集整理的python – 通过SWIG传递函数指针数组全部内容,希望文章能够帮你解决python – 通过SWIG传递函数指针数组所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)