swig3用模板化的constru包装未模板化的类

2024-09-26 21:42:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我们有一个模板化的构造函数的非模板C++类。我们可以使用swig2来制作Python包装器,但是swig3中的代码失败了:包装器类的构造函数引发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接口文件的主要部分:

^{pr2}$

我考虑过的一个粗略的解决方法是用每个专门化的显式版本替换头中的模板化构造函数,例如:

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++头。在

不过,我还是希望有一个更简单的解决方案。我们想更新为C++ 11支持的Sug 3,但这是一个重要的拦截器。在


Tags: image模板trueimgthresholdswigintbool
2条回答

编译器可能需要一些帮助来确定Image是模板化类型。{cd2>尝试}:

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:

^{pr2}$

在swig3.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

建议你往上游踢。在


编辑:这是fixed upstream。在

相关问题 更多 >

    热门问题