Как выставить функцию, возвращающую объект C ++ на Python с помощью Cython?

Я строю C ++ <-> привязки Python с помощью Cython, и я не могу найти, как вернуть объект C ++ из метода Python.

Более конкретно, при компиляции peak_detection_.pyx , показанного ниже, я получаю

 peak_detection_.pyx:35:36: Cannot convert 'vector[Peak]' to Python object 

для последних строк

 def getPeaks(self,data): return self.thisptr.getPeaks(data) 

Я понимаю ошибку, но я не возражаю против помощи / указателей о том, как ее исправить.

peak_detection.hpp

 #ifndef PEAKDETECTION_H #define PEAKDETECTION_H #include <string> #include <map> #include <vector> #include "peak.hpp" class PeakDetection { public: PeakDetection(std::map<std::string, std::string> config); std::vector<Peak> getPeaks(std::vector<float> &data); private: float _threshold; }; #endif 

peak_detection.cpp

 #include <iostream> #include <string> #include "peak.hpp" #include "peak_detection.hpp" using namespace std; PeakDetection::PeakDetection(map<string, string> config) { _threshold = stof(config["_threshold"]); } vector<Peak> PeakDetection::getPeaks(vector<float> &data){ Peak peak1 = Peak(10,1); Peak peak2 = Peak(20,2); vector<Peak> test; test.push_back(peak1); test.push_back(peak2); return test; } 

peak.hpp

 #ifndef PEAK_H #define PEAK_H class Peak { public: float freq; float mag; Peak() : freq(), mag() {} Peak(float f, float m) : freq(f), mag(m) {} }; #endif 

peak_detection_.pyx

 # distutils: language = c++ # distutils: sources = peak_detection.cpp from libcpp.vector cimport vector from libcpp.map cimport map from libcpp.string cimport string cdef extern from "peak.hpp": cdef cppclass Peak: Peak() cdef class PyPeak: cdef Peak *thisptr def __cinit__(self): self.thisptr = new Peak() def __dealloc__(self): del self.thisptr cdef extern from "peak_detection.hpp": cdef cppclass PeakDetection: PeakDetection(map[string,string]) vector[Peak] getPeaks(vector[float]) cdef class PyPeakDetection: cdef PeakDetection *thisptr def __cinit__(self, map[string,string] config): self.thisptr = new PeakDetection(config) def __dealloc__(self): del self.thisptr def getPeaks(self, data): return self.thisptr.getPeaks(data) 

One Solution collect form web for “Как выставить функцию, возвращающую объект C ++ на Python с помощью Cython?”

Ваша проблема здесь в том, что cython не знает, как автоматически преобразовать объект C ++ Peak в PyPeak версию PyPeak на основе python.

Версия, которая скопирует экземпляры Peak которые getPeaks вернет в список экземпляров PyPeak , будет:

 # distutils: language = c++ # distutils: sources = peak_detection.cpp from libcpp.vector cimport vector from libcpp.map cimport map from libcpp.string cimport string cdef extern from "peak.hpp": cdef cppclass Peak: Peak() Peak(Peak &) float freq, mag cdef class PyPeak: cdef Peak *thisptr def __cinit__(self): self.thisptr = new Peak() def __dealloc__(self): del self.thisptr cdef copy(self, Peak &other): del self.thisptr self.thisptr = new Peak(other) def __repr__(self): return "<Peak: freq={0}, mag={1}>".format(self.freq, self.mag) property freq: def __get__(self): return self.thisptr.freq def __set__(self, freq): self.thisptr.freq = freq property mag: def __get__(self): return self.thisptr.mag def __set__(self, mag): self.thisptr.mag = mag cdef extern from "peak_detection.hpp": cdef cppclass PeakDetection: PeakDetection(map[string,string]) vector[Peak] getPeaks(vector[float]) cdef class PyPeakDetection: cdef PeakDetection *thisptr def __cinit__(self, map[string,string] config): self.thisptr = new PeakDetection(config) def __dealloc__(self): del self.thisptr def getPeaks(self, data): cdef Peak peak cdef PyPeak new_peak cdef vector[Peak] peaks = self.thisptr.getPeaks(data) retval = [] for peak in peaks: new_peak = PyPeak() new_peak.copy(peak) retval.append(new_peak) return retval 

После компиляции и запуска получаем ожидаемый результат:

 In [1]: import peak_detection_ In [2]: print peak_detection_.PyPeakDetection({"_threshold" : "0.01"}).getPeaks([1,2,3]) [<Peak: freq=10.0, mag=1.0>, <Peak: freq=20.0, mag=2.0>] 
  • Как удалить строки документа при использовании Cython distutils?
  • Вектор C ++ для Python 3.3
  • Быстрый n-мерный разреженный массив в Python / Cython
  • Вызовите функцию python в C-коде
  • Как исследовать функцию, определенную в модуле расширения Cython C
  • Синтаксис Cython для объявления иерархии классов, которые имеют псевдонимы
  • C массив против массива NumPy
  • Как использовать что-то вроде openMP в Cython?
  • Python - лучший язык программирования в мире.