2017-12-22 9 views
2

Ich bin ein Neuling für C++ und Cython, und verwirrt über das Umwickeln eines C++ - Friend Nichtmitglieds-Operator in Cython. Hier ist ein kleines Beispiel, das ich versuche zu umbrechen, aber gescheitert ist. Schätzen Sie vielWrapping C++ Freund Nicht-Mitglied-Operator in Cython

Nun, wie kann ich den Freund Operator in pyx Datei

all files can be found here, makefile for test erklären -

Rectangle.h

namespace shapes { 
    class Rectangle { 
     public: 
     int x0, y0, x1, y1; 
     Rectangle(int x0=0, int y0=0, int x1=0, int y1=0); 
     ~Rectangle(); 
     int getLength(); 
     Rectangle operator+(const Rectangle& target); 
     friend Rectangle operator-(const Rectangle & left, const Rectangle & right); 
    }; 
    } 

Rectangle.cpp

#include "Rectangle.h" 

using namespace shapes; 

Rectangle::Rectangle(int X0, int Y0, int X1, int Y1) { 
    x0 = X0; 
    y0 = Y0; 
    x1 = X1; 
    y1 = Y1; 
} 


int Rectangle::getLength() { 
    return (x1 - x0); 
} 

Rectangle::~Rectangle() 
{ 

} 

Rectangle Rectangle::operator+(const Rectangle & target) { 
    return Rectangle(x0+target.x0, y0+target.y0,x1+target.x1,y1+target.y1); 
} 

Rectangle operator-(const Rectangle & left,const Rectangle & right) { 
    return Rectangle(left.x0 - right.x0, 
        left.y0-right.y0, 
        left.x1-right.x1, 
        left.y1-right.y1); 
} 

pyx Datei

from libcpp.vector cimport vector 
from cython.operator cimport dereference as deref 

# c++ interface to cython 
cdef extern from "Rectangle.h" namespace "shapes": 
    cdef cppclass Rectangle: 
     Rectangle() except + 
     Rectangle(int, int, int, int) except + 
     int x0, y0, x1, y1 
     int getLength() 
     Rectangle opadd "operator+"(Rectangle right) 
     Rectangle opsub "operator-" (Rectangle right) 
    # Rectangle opsub "operator-"(Rectangle left ,Rectangle right) 

# cdef extern from "Rectangle.h" namespace "shapes": 
#  cdef Rectangle opsub "operator-"(Rectangle left ,Rectangle right) 

# creating a cython wrapper class 
cdef class PyRectangle: 
    cdef Rectangle *thisptr  # hold a C++ instance which we're wrapping 
    def __cinit__(self, int x0=0, int y0=0, int x1=0, int y1=0): 
     self.thisptr = new Rectangle(x0, y0, x1, y1) 
    def __dealloc__(self): 
     del self.thisptr 
    def getLength(self): 
     return self.thisptr.getLength() 
    def __add__(PyRectangle left,PyRectangle right): 
     cdef Rectangle rect = left.thisptr.opadd(right.thisptr[0]) 
     cdef PyRectangle sum = PyRectangle(rect.x0,rect.y0,rect.x1,rect.y1) 
     return sum 
    def __sub__(PyRectangle left,PyRectangle right): 
     cdef Rectangle rect = left.thisptr.opsub(right.thisptr[0]) 
     # cdef Rectangle rect = opsub(left.thisptr[0],right.thisptr[0]) 
     cdef PyRectangle sub = PyRectangle(rect.x0,rect.y0,rect.x1,rect.y1) 
     return sub 
    def __repr__(self): 
     return "PyRectangle[%s,%s,%s,%s]" % (
       self.thisptr.x0, 
       self.thisptr.y0, 
       self.thisptr.x1, 
       self.thisptr.y1) 

Ich habe Serval Ansätze ausprobiert, wie

cdef extern from "Rectangle.h" namespace "shapes": 
    cdef Rectangle opsub "operator-"(Rectangle left ,Rectangle right) 

oder nur so tun, es

Rectangle opsub "operator-" (Rectangle right) 

ich nicht in beiden Richtungen kompilieren, ein Mitglied definierte Operator in der cppclass Erklärung zu sein wie es zeigt

error: no member named 'operator-' in 'shapes::Rectangle' 
+0

Gerade nannte es betreiber- sollte – DavidW

+0

arbeiten (und Sie nennen es in Cython als 'links right' http://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html#overloading -Operatoren) – DavidW

Antwort

1

So Ich fand einen großen Fehler in der Rectangle.cpp. Die Definition der betreiber Bedürfnisse mit Namespace zu dem Präfix

Rectangle shapes::operator-(const Rectangle & left,const Rectangle & right) { 
    return Rectangle(left.x0 - right.x0, 
        left.y0-right.y0, 
        left.x1-right.x1, 
        left.y1-right.y1); 
} 

Und rect.pyx kann modifiziert werden Betreiber in Verbindung direkt nach Hinweisen von DavidW.

# c++ interface to cython 
cdef extern from "Rectangle.h" namespace "shapes": 
    cdef cppclass Rectangle: 
     Rectangle() except + 
     Rectangle(int, int, int, int) except + 
     int x0, y0, x1, y1 
     int getLength() 
     Rectangle operator+(Rectangle right) 
     Rectangle operator-(Rectangle right) 

#### nonmember operator can also work : 
# cdef extern from "Rectangle.h" namespace "shapes": 
    # cdef Rectangle operator-(Rectangle left ,Rectangle right) 

# creating a cython wrapper class 
cdef class PyRectangle: 
    cdef Rectangle *thisptr  # hold a C++ instance which we're wrapping 
    def __cinit__(self, int x0=0, int y0=0, int x1=0, int y1=0): 
     self.thisptr = new Rectangle(x0, y0, x1, y1) 
    def __dealloc__(self): 
     del self.thisptr 
    def getLength(self): 
     return self.thisptr.getLength() 
    def __add__(PyRectangle left,PyRectangle right): 
     cdef Rectangle rect = left.thisptr[0] + right.thisptr[0] 
     cdef PyRectangle sum = PyRectangle(rect.x0,rect.y0,rect.x1,rect.y1) 
     return sum 
    def __sub__(PyRectangle left,PyRectangle right): 
     cdef Rectangle rect = left.thisptr[0] - right.thisptr[0] 
     # cdef Rectangle rect = opsub(left.thisptr[0],right.thisptr[0]) 
     cdef PyRectangle sub = PyRectangle(rect.x0,rect.y0,rect.x1,rect.y1) 
     return sub