2017-12-22 3 views
2

저는 C++과 cython 모두를 초보자로 삼아 Cython에서 C++ friend 비회원 연산자를 래핑하는 것에 대해 혼란 스럽습니다. 여기에 제가 포장하려고 시도하고 있지만 실패한 작은 예가 있습니다. 많은 지금 Cython의 C++ friend 비회원 연산자

을 감사합니다, 나는 PYX 파일의 친구 연산자를 선언 할 수있는 방법을

all files can be found here, makefile for test -

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 파일

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) 

내가 Serval의 접근을 시도, 같은

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

또는 그냥 내가 두 가지를 컴파일하는 데 실패

Rectangle opsub "operator-" (Rectangle right) 

cppclass 선언 내부 구성원 정의 연산자 척, 나타내는대로

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

그냥 운용자 – DavidW

+0

를 작동해야 호출 (당신은 왼쪽 right' http://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html#overloading'로 사이 썬에 전화 - 운영자) – DavidW

답변

1

So rry, Rectangle.cpp에서 큰 실수를 발견했습니다. 운용자 요구의 정의 네임 스페이스

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); 
} 

그리고 rect.pyx 붙여야하는 직접 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