![](/img/trans.png)
[英]SWIG - How to wrap to python a class with a constructor that takes a 'const double*'
[英]SWIG 3 wrap untemplated class with templated constructor
我們有一個帶有模板構造函數的非模板C ++類。 我們可以使用SWIG 2來制作Python包裝器,但是在SWIG 3中,相同的代碼將失敗:包裝器類的構造函數引發AttributeError(“未定義構造函數”)。 我希望有人可以提出干凈的修復或解決方法。
這是C ++標頭的摘錄:
class FootprintSet {
public:
template <typename ImagePixelT>
FootprintSet(image::Image<ImagePixelT> const& img,
Threshold const& threshold,
int const npixMin=1, bool const setPeaks=true);
FootprintSet(geom::Box2I region);
...
以及SWIG接口文件的主要部分:
%shared_ptr(lsst::afw::detection::FootprintSet);
%include "lsst/afw/detection/FootprintSet.h"
%define %footprintSetOperations(PIXEL)
%template(FootprintSet) FootprintSet<PIXEL>;
%enddef
%extend lsst::afw::detection::FootprintSet {
%footprintSetOperations(boost::uint16_t)
%footprintSetOperations(int)
%footprintSetOperations(float)
%footprintSetOperations(double)
}
我考慮過的一種粗略的解決方法是用每種專業的顯式版本替換標頭中的模板化構造函數,例如:
class FootprintSet {
public:
#ifndef SWIG
template <typename ImagePixelT>
FootprintSet(image::Image<ImagePixelT> const& img,
Threshold const& threshold,
int const npixMin=1, bool const setPeaks=true);
#else
FootprintSet(image::Image<boost::unit16> const& img,
Threshold const& threshold,
int const npixMin=1, bool const setPeaks=true);
FootprintSet(image::Image<int> const& img,
Threshold const& threshold,
int const npixMin=1, bool const setPeaks=true);
FootprintSet(image::Image<float> const& img,
Threshold const& threshold,
int const npixMin=1, bool const setPeaks=true);
FootprintSet(image::Image<double> const& img,
Threshold const& threshold,
int const npixMin=1, bool const setPeaks=true);
#endif
FootprintSet(geom::Box2I region);
...
或者(可能更好)在SWIG接口中放置類似的內容,而不是C ++標頭。
不過,我希望有一個更簡單的解決方案。 我們希望將SWIG 3更新為C ++ 11支持,但這是一個重要的阻止因素。
編譯器可能需要一些幫助,才能確定Image
是模板化類型。 嘗試輸入typename
:
FootprintSet(typename image::Image<ImagePixelT> const& img, ...
在SWIG中似乎確實是回歸。 這是一個簡化的示例:
price@price-laptop:~/test $ cat test.h
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <typeinfo>
namespace test {
class Foo
{
public:
template<typename T>
Foo(T bar);
~Foo() {}
void working() const {
std::cout << "WORKING" << std::endl;
}
};
}
#endif
price@price-laptop:~/test $ cat test.cc
#include "test.h"
namespace test {
template <typename T>
Foo::Foo(T) {
std::cout << typeid(T).name() << std::endl;
}
template Foo::Foo(int);
}
price@price-laptop:~/test $ cat test.i
%feature("autodoc", "1");
%module(package="test", docstring="test") testLib
%{
#include "test.h"
%}
%include "test.h"
%extend test::Foo {
%template(Foo) Foo<int>;
}
price@price-laptop:~/test $ clang++ -shared -undefined dynamic_lookup -o libtest.dylib test.cc
使用SWIG 2.0.12:
price@price-laptop:~/test $ swig -python -c++ test.i
price@price-laptop:~/test $ clang++ -shared -undefined dynamic_lookup -o _testLib.so test_wrap.cxx -L. -ltest -I/usr/include/python2.7
price@price-laptop:~/test $ python -c "import testLib; testLib.Foo(1)"
i
在SWIG 3.0.2中,似乎將Foo::Foo
視為普通函數,警告它沒有返回類型,並忽略它:
price@price-laptop:~/test $ swig -python -c++ test.i
test.i:11: Warning 504: Function test::Foo::Foo(int) must have a return type. Ignored.
price@price-laptop:~/test $ clang++ -shared -undefined dynamic_lookup -o _testLib.so test_wrap.cxx -L. -ltest -I/usr/include/python2.7
price@price-laptop:~/test $ python -c "import testLib; testLib.Foo(1)"Traceback (most recent call last):
File "<string>", line 1, in <module>
File "testLib.py", line 82, in __init__
def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined")
AttributeError: No constructor defined
建議您向上游踢。
編輯:這已修復上游 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.