I have a C++ function which returns a pointer double**
- a high dimensional matrix in particular - and I'd like to wrap it to some python code using Cython. How should I act?
Here an example with a function with a double*
pointer for sake of simplicity.
My C++ fib.cpp
code:
double add(double a, double b)
{
return a+b;
}
double p[]= {1,2,3,4};
double* mult(double a)
{
p[0]=p[0]*a;
p[1]=p[1]*a;
return p;
}
Then there is the fib.hpp
file:
double add(double a,double b);
double* mult(double a);
Then the pxd file fib.pxd
:
cdef extern from "fib.hpp":
double add(double a,double b);
double* mult(double a);
In the end the pyx file
# distutils: language = c++
# distutils: sources = fib.cpp
cimport fib
def add(a,b):
return fib.add(a,b)
def mult(a): # dropping these lines
return fib.mult(a) # the code works without the double* function
Everything is compiled with the rather standard setup.py
:
from distutils.core import setup, Extension
from Cython.Build import cythonize
ext = Extension("fib2cpp",
sources=["fib.pyx", "fib.cpp"],
language="c++")
setup(name="fib",
ext_modules=cythonize(ext))
When I compile the code:
setup.py build_ext -if
Cannot convert '
double *
' to python object.
When I try with a double**
function I get the same error. What should I do?
I have found a solution for the case double *
. First of all, the file fib.pxd
is useless. Then we need a new fib.pyx
file:
# distutils: language = c++
# distutils: sources = fib.cpp
import numpy as np
cimport numpy as cnp
cdef extern from "fib.hpp":
double fib(int n)
double add (double a, double b)
double* mult(double a)
def make_mult(double a):
cdef double[:] mv = <double[:4]> mult(a) # the 4 stands for
return np.asarray(mv) # the dimension of the array defined in fib.cpp
In the case of a function which returns a nrows*ncols matrix; such as double* make_mat(int nrows, int ncols)
, the second line of the function make_mult
has to be rewritten as:
cdef double[:,:] mv=<double[:nrows,:ncols]> make_mat(nrows, ncols)
Regrettably, If I have a function double** make_mat(int nrows, int ncols)
which always returns a matrix, then the previous code rises the error :
Pointer base type does not match cython.array base type
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.