2012-11-09 52 views
1

我有C++類,需要在python代碼中使用它。爲了使用swig生成一個包裝類。按照文件中配置的example.iswig build問題 - python

/* File: example.i */ 
%module example 

%{ 
#define SWIG_FILE_WITH_INIT 
#include "item.h" 
#include "GradedComplex.h" 
#include "GradedDouble.h" 
%} 

%include "item.h" 
%include "GradedComplex.h" 
%include "GradedDouble.h" 

,我試圖在Windows

c:>swig -c++ -python example.i 

c:>python setup.py build_ext --inplace 

建立使用痛飲的包裝類執行第二個命令我收到以下錯誤後。

example_wrap.cxx 
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\xlocale(342) : warning C 
4530: C++ exception handler used, but unwind semantics are not enabled. Specify 
/EHsc 
c:\documents and settings\swig\item.h(73) : warning C45 
21: 'Item<std::complex<double>>' : multiple copy constructors specified 
c:\documents and settings\swig\item.h(57) : error C2106 
: '+=' : left operand must be l-value 
c:\documents and settings\swig\item.h(58) : error C2106 
: '+=' : left operand must be l-value 
c:\documents and settings\swig\item.h(63) : error C2106 
: '-=' : left operand must be l-value 
c:\documents and settings\swig\item.h(64) : error C2106 
: '-=' : left operand must be l-value 
c:\documents and settings\swig\item.h(69) : error C2106 
: '=' : left operand must be l-value 
c:\documents and settings\swig\item.h(70) : error C2106 
: '=' : left operand must be l-value 
example_wrap.cxx(3275) : error C2512: 'Item<std::complex<double>>' : no appropriate default constructor available 

c:\documents and settings\swig\Item.h(38) : warning C45 
21: 'Item<T>' : multiple copy constructors specified 
     with 
     [ 
      T=double 
     ] 
     example_wrap.cxx(3425) : see reference to class template instantiation ' 
Item<T>' being compiled 
     with 
     [ 
      T=double 
     ] 
error: command '"C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe"' fa 
iled with exit status 2 

的item.h如下

#ifndef __ITEM_H__ 
#define __ITEM_H__ 

#include <complex> 
#include <functional> 
#include <string> 

template<typename T> 
class Item 
{ 
    std::string name_; 
    T val_; 

public: 
    Item(std::string name, T val) : name_(name), val_(val) {} 
    Item(Item<T> &rhs) : name_(rhs.name_), val_(rhs.val_) {} 
    Item(const Item<T> &rhs) : name_(rhs.name_), val_(rhs.val_) {} 
    ~Item() {} 

    std::string name() const { return name_; } 
    T operator()() const { return val_; } 
    double norm() const { return sqrt(val_ * val_); } 
    Item<T> &operator+=(Item<T> &rhs) 
    { 
    val_ += rhs(); 
    return *this; 
    } 
    Item<T> &operator-=(Item<T> &rhs) 
    { 
    val_ -= rhs(); 
    return *this; 
    } 
    Item<T> &operator*=(Item<T> &rhs) 
    { 
    val_ *= rhs(); 
    return *this; 
    } 
}; 

template<> 
class Item<std::complex<double> > 
{ 
    std::string name_; 
    std::complex<double> val_; 

public: 
    Item(std::string name, std::complex<double> val) : name_(name), val_(val) {} 
    Item(Item<std::complex<double> > &rhs) : name_(rhs.name_), val_(rhs.val_) {} 
    Item(const Item<std::complex<double> > &rhs) : name_(rhs.name_), val_(rhs.val_) {} 
    ~Item() {} 

    std::string name() const { return name_; } 
    std::complex<double> operator()() const { return val_; } 
    double norm() const { return sqrt(val_.real() * val_.real() + val_.imag() * val_.imag()); } 
    Item<std::complex<double> > &operator+=(Item<std::complex<double> > &rhs) 
    { 
    val_.real() += rhs().real(); 
    val_.imag() += rhs().imag(); 
    return *this; 
    } 
    Item<std::complex<double> > &operator-=(Item<std::complex<double> > &rhs) 
    { 
    val_.real() -= rhs().real(); 
    val_.imag() -= rhs().imag(); 
    return *this; 
    } 
    Item<std::complex<double> > &operator*=(Item<std::complex<double> > &rhs) 
    { 
    val_.real() = val_.real() * rhs().real() - val_.imag() * rhs().imag(); 
    val_.imag() = val_.real() * rhs().imag() + val_.imag() * rhs().real(); 
    return *this; 
    } 
}; 

template<typename T> 
struct ItemComparator : public std::binary_function<Item<T>, Item<T>, bool> 
{ 
    inline bool operator()(Item<T> lhs, Item<T> rhs) 
    { 
    return lhs.norm() < rhs.norm(); 
    } 
}; 

#endif 

回答

1

你必須在C++代碼中的錯誤。 std::complex::real()不返回左值,所以這並不編譯:

Item<std::complex<double> > &operator+=(Item<std::complex<double> > &rhs) 
    { 
    val_.real() += rhs().real(); 
    val_.imag() += rhs().imag(); 
    return *this; 
    } 

你可以只使用這樣的:

val_ += rhs(); 
+0

感謝您的回覆 –