経由だろう、私はあなたが何をしようとして説明するために、次のテストケースを作りました。
%include <std_vector.i>
%template(FunVec) std::vector<double(*)(double)>;
%template(DoubleVec) std::vector<double>;
%include "test.h"
しかしSWIG 3.0(:
#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;
}
は、私たちはこの仕事をするために行う必要があるだろう、すべてが使用されることを期待:それは人生もう少し面白くするためにmyfun(const std::vector<double(*)(double)>&)
の実際の実装を持っていますDebian stableから)はFunVec
を正しく処理せず、結果のモジュールはコンパイルされません。だから私は、回避策として、タイプマップを追加しました:
%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);
$1 = &tmp;
}
%include <std_vector.i>
// Doesn't work:
//%template(FunVec) std::vector<double(*)(double)>;
%template(DoubleVec) std::vector<double>;
%include "test.h"
を基本的にこれが行うすべてが関数ポインタ型のベクトルのためのタイプマップ「で」1を追加することです。そのtypemapは、Pythonから与えられた入力を反復処理し、Pythonの反復可能プログラムから一時的に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)
πάντα@基本的な実施例ῥεῖは同じですが、質問は異なっています。 dupとしてマークを外してください。 –
あなたの質問を一番良くしてください。 –
不明な点は何ですか? –