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

python – 通过SWIG传递函数指针数组,第1张

概述在 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) 在 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 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传递函数指针数组所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1197694.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存