How to create a public cython function that can receive c++ struct/instance or python object as parameter? -


my rectangle.h

namespace shapes {     class rectangle {     public:         int x0, y0, x1, y1;         rectangle();         rectangle(int x0, int y0, int x1, int y1);         ~rectangle();         int getarea();     }; } 

my rectangle.cpp

#include "rectangle.h" namespace shapes {   rectangle::rectangle() { }     rectangle::rectangle(int x0, int y0, int x1, int y1) {         x0 = x0;         y0 = y0;         x1 = x1;         y1 = y1;     }     rectangle::~rectangle() { }     int rectangle::getarea() {         return (x1 - x0) * (y1 - y0);     } } 

my rect.pyx

# distutils: language = c++ # distutils: sources = rectangle.cpp  cdef extern "rectangle.h" namespace "shapes":     cdef cppclass rectangle:         rectangle() except +         rectangle(int, int, int, int) except +         int x0, y0, x1, y1         int getarea()  cdef class pyrectangle:     cdef rectangle c_rect     def __cinit__(self, int x0, int y0, int x1, int y1):         self.c_rect = rectangle(x0, y0, x1, y1)     def get_area(self):         return self.c_rect.getarea()  cdef public int cythonfunc(pyrectangle py_rect):     result = py_rect.get_area()     return result 

my main.cpp

#include <python.h>  #include "rect.h"  #include "rectangle.h" #include <iostream>  int main (int argc, char *argv[]) {   int result;   py_initialize();    pyinit_rect();   shapes::rectangle c_rect = shapes::rectangle(0,0,2,1);   result = cythonfunc(c_rect);   std::cout<<result<<"\n";    py_finalize();    return 0; } 

my makefile

all:         cython3 --cplus rect.pyx         c++ -g -o2 -c rect.cpp -o rect.o `python3-config --includes`         c++ -g -o2 -c rectangle.cpp -o rectangle.o `python3-config --includes`         c++ -g -o2 -c main.cpp -o main.o `python3-config --includes`         c++ -g -o2 -o rect rectangle.o rect.o main.o `python3-config --libs`  clean:         rm -f rect rect.cpp rect.h *.o 

my problem related "cythonfunc" in rect.pyx. intended public function can called main rectangle struct/object parameter, , return area main.cpp.

i've tried c struct , python object, both not work me. if use codes, compiler gives error of

error compiling cython file: ------------------------------------------------------------ ...     def __cinit__(self, int x0, int y0, int x1, int y1):         self.c_rect = rectangle(x0, y0, x1, y1)     def get_area(self):         return self.c_rect.getarea()  cdef public int cythonfunc(pyrectangle py_rect):                           ^ ------------------------------------------------------------  rect.pyx:19:27: function declared public or api may not have private types 

so added "public" pyrectangle, got error:

error compiling cython file: ------------------------------------------------------------ ...         rectangle() except +         rectangle(int, int, int, int) except +         int x0, y0, x1, y1         int getarea()  cdef public class pyrectangle:     ^ ------------------------------------------------------------  rect.pyx:12:5: type object name specification required 'public' c class 

if change cythonfunc to:

cdef public int cythonfunc(rectangle c_rect):     result = c_rect.getarea()     return result 

i got error of:

in file included main.cpp:3:0: rect.h:21:42: warning: ‘cythonfunc’ initialized , declared ‘extern’  __pyx_extern_c dl_import(int) cythonfunc(shapes::rectangle);                                           ^ rect.h:21:42: error: ‘shapes’ has not been declared main.cpp: in function ‘int main(int, char**)’: main.cpp:17:29: error: ‘cythonfunc’ cannot used function    result = cythonfunc(c_rect);                              ^ 

i can success passing separate x0, y0, x1, y1 parameter cythonfunc. there correct way passing cpp struct/object or python object parameter cython public function?

with respect second attempt (which more sensible way of calling c++, although i'd pass reference):

cdef public int cythonfunc(rectangle c_rect):     result = c_rect.getarea()     return result 

the issue doesn't know rectangle is, since cython generated rect.h doesn't include rectangle.h. easiest way fix swap order of includes in main.cpp:

#include "rectangle.h" // 1 first #include "rect.h" 

the error "shapes has not been declared" telling this...


with respect first attempt, right have make pyrectangle public. need specify "type object name" cython tells you. shown here (although isn't hugely clear...):

cdef public class pyrectangle [object c_pyrect, type c_pyrect_t]:     # ... before 

this ensures pyrectangle available c/c++ struct c_pyrect (and cythonfunc signature int cythonfunc(struct c_pyrect *);.)

also, python typeobject defining pyrectangle available c_pyrect_t, don't need that.


Comments

Popular posts from this blog

php - How to display all orders for a single product showing the most recent first? Woocommerce -

asp.net - How to correctly use QUERY_STRING in ISAPI rewrite? -

angularjs - How restrict admin panel using in backend laravel and admin panel on angular? -