C++ Python Ctypes调用C++;功能
我尝试使用Python cType来与发布的(封闭源代码)C++库接口。I(尝试)编写了一个基本的C样式函数包装器来构造C++向量样式对象并调用C++例程。我还(尝试)编写了一个基本的python脚本来加载共享库。除了调用C++例程的行外,其他都在工作:C++ Python Ctypes调用C++;功能,c++,python,c,segmentation-fault,ctypes,C++,Python,C,Segmentation Fault,Ctypes,我尝试使用Python cType来与发布的(封闭源代码)C++库接口。I(尝试)编写了一个基本的C样式函数包装器来构造C++向量样式对象并调用C++例程。我还(尝试)编写了一个基本的python脚本来加载共享库。除了调用C++例程的行外,其他都在工作: *** glibc detected *** python: free(): invalid next size (fast): 0x0000000001e73c00 *** #include "nr3.h" #include "choles
*** glibc detected *** python: free(): invalid next size (fast): 0x0000000001e73c00 ***
#include "nr3.h"
#include "cholesky.h"
#include "gaumixmod.h"
extern "C" {
void cGaumixmod(double* D, int Dm, int Dn, double* M, int Mm, int Mn) {
MatDoub ddata(Dm,Dn,*D); // construct Matrix (vector) type
MatDoub mmeans(Mm,Mn,*M); // construct Matrix (vector) type
//XXX test numpy array is coming through as C array and we can rw, checks OK
int i;
// for(i=0;i<Dn*Dm;++i) {
// printf("Address %x : ",(D+i));
// printf("was %f \t" , D[i]);
// D[i]+=1.0;
// printf("now: %f \n" , D[i]);
// }
// check that array D was copied to matrix ddata, and we can r/w
for(i=0;i<Dm*Dn;++i) {
printf("iter %d Address %x : ",i,ddata[i/Dm][i%Dm]);
printf("was %f \t" , ddata[i/Dm][i%Dm]);
ddata[i/Dm][i%Dm]+=1.0;
printf("now: %f \n" ,ddata[i/Dm][i%Dm]);
}
Gaumixmod::Gaumixmod(ddata,mmeans);
//return data from vector to ctypes array C so we can check data returns to python
//via numpy array, checks ok
for(i=0;i<Dm*Dn;++i) {
D[i] = ddata[i/Dm][i%Dm];
}
}
}
这里是文件,不幸的是我不能共享标题,但如果需要,我可以写一些类似的东西
#include "nr3.h"
#include "cholesky.h"
#include "gaumixmod.h"
extern "C" {
void cGaumixmod(double* D, int Dm, int Dn, double* M, int Mm, int Mn) {
MatDoub ddata(Dm,Dn,*D); // construct Matrix (vector) type
MatDoub mmeans(Mm,Mn,*M); // construct Matrix (vector) type
//XXX test numpy array is coming through as C array and we can rw, checks OK
int i;
// for(i=0;i<Dn*Dm;++i) {
// printf("Address %x : ",(D+i));
// printf("was %f \t" , D[i]);
// D[i]+=1.0;
// printf("now: %f \n" , D[i]);
// }
// check that array D was copied to matrix ddata, and we can r/w
for(i=0;i<Dm*Dn;++i) {
printf("iter %d Address %x : ",i,ddata[i/Dm][i%Dm]);
printf("was %f \t" , ddata[i/Dm][i%Dm]);
ddata[i/Dm][i%Dm]+=1.0;
printf("now: %f \n" ,ddata[i/Dm][i%Dm]);
}
Gaumixmod::Gaumixmod(ddata,mmeans);
//return data from vector to ctypes array C so we can check data returns to python
//via numpy array, checks ok
for(i=0;i<Dm*Dn;++i) {
D[i] = ddata[i/Dm][i%Dm];
}
}
}
gaumixmod.cpp:
#include "nr3.h"
#include "cholesky.h"
#include "gaumixmod.h"
extern "C" {
void cGaumixmod(double* D, int Dm, int Dn, double* M, int Mm, int Mn) {
MatDoub ddata(Dm,Dn,*D); // construct Matrix (vector) type
MatDoub mmeans(Mm,Mn,*M); // construct Matrix (vector) type
//XXX test numpy array is coming through as C array and we can rw, checks OK
int i;
// for(i=0;i<Dn*Dm;++i) {
// printf("Address %x : ",(D+i));
// printf("was %f \t" , D[i]);
// D[i]+=1.0;
// printf("now: %f \n" , D[i]);
// }
// check that array D was copied to matrix ddata, and we can r/w
for(i=0;i<Dm*Dn;++i) {
printf("iter %d Address %x : ",i,ddata[i/Dm][i%Dm]);
printf("was %f \t" , ddata[i/Dm][i%Dm]);
ddata[i/Dm][i%Dm]+=1.0;
printf("now: %f \n" ,ddata[i/Dm][i%Dm]);
}
Gaumixmod::Gaumixmod(ddata,mmeans);
//return data from vector to ctypes array C so we can check data returns to python
//via numpy array, checks ok
for(i=0;i<Dm*Dn;++i) {
D[i] = ddata[i/Dm][i%Dm];
}
}
}
我编译这个jazz时使用了:
#include "nr3.h"
#include "cholesky.h"
#include "gaumixmod.h"
extern "C" {
void cGaumixmod(double* D, int Dm, int Dn, double* M, int Mm, int Mn) {
MatDoub ddata(Dm,Dn,*D); // construct Matrix (vector) type
MatDoub mmeans(Mm,Mn,*M); // construct Matrix (vector) type
//XXX test numpy array is coming through as C array and we can rw, checks OK
int i;
// for(i=0;i<Dn*Dm;++i) {
// printf("Address %x : ",(D+i));
// printf("was %f \t" , D[i]);
// D[i]+=1.0;
// printf("now: %f \n" , D[i]);
// }
// check that array D was copied to matrix ddata, and we can r/w
for(i=0;i<Dm*Dn;++i) {
printf("iter %d Address %x : ",i,ddata[i/Dm][i%Dm]);
printf("was %f \t" , ddata[i/Dm][i%Dm]);
ddata[i/Dm][i%Dm]+=1.0;
printf("now: %f \n" ,ddata[i/Dm][i%Dm]);
}
Gaumixmod::Gaumixmod(ddata,mmeans);
//return data from vector to ctypes array C so we can check data returns to python
//via numpy array, checks ok
for(i=0;i<Dm*Dn;++i) {
D[i] = ddata[i/Dm][i%Dm];
}
}
}
g++ -fPIC -c gaumixmod.cpp;
g++ -shared -o gaumixmod.so gaumixmod.o
跑
#include "nr3.h"
#include "cholesky.h"
#include "gaumixmod.h"
extern "C" {
void cGaumixmod(double* D, int Dm, int Dn, double* M, int Mm, int Mn) {
MatDoub ddata(Dm,Dn,*D); // construct Matrix (vector) type
MatDoub mmeans(Mm,Mn,*M); // construct Matrix (vector) type
//XXX test numpy array is coming through as C array and we can rw, checks OK
int i;
// for(i=0;i<Dn*Dm;++i) {
// printf("Address %x : ",(D+i));
// printf("was %f \t" , D[i]);
// D[i]+=1.0;
// printf("now: %f \n" , D[i]);
// }
// check that array D was copied to matrix ddata, and we can r/w
for(i=0;i<Dm*Dn;++i) {
printf("iter %d Address %x : ",i,ddata[i/Dm][i%Dm]);
printf("was %f \t" , ddata[i/Dm][i%Dm]);
ddata[i/Dm][i%Dm]+=1.0;
printf("now: %f \n" ,ddata[i/Dm][i%Dm]);
}
Gaumixmod::Gaumixmod(ddata,mmeans);
//return data from vector to ctypes array C so we can check data returns to python
//via numpy array, checks ok
for(i=0;i<Dm*Dn;++i) {
D[i] = ddata[i/Dm][i%Dm];
}
}
}
python gaumixmod.py
我的研究表明,这个错误类似于segFault,python试图访问超出其范围的内存。。。这是我不理解的部分,因为注释C++行GAUMIXMOD::GUMIXMODE(),所有的工作都很好,并且例程应该在CGAUMIXMODE()函数中实例化的向量上运行,而不是Python Nuffy数组。我对C++非常陌生,虽然我已经多次使用C类型来支持C库。我希望有C++、Python和cType体验的人能在这里提供一些见解/指导。
#include "nr3.h"
#include "cholesky.h"
#include "gaumixmod.h"
extern "C" {
void cGaumixmod(double* D, int Dm, int Dn, double* M, int Mm, int Mn) {
MatDoub ddata(Dm,Dn,*D); // construct Matrix (vector) type
MatDoub mmeans(Mm,Mn,*M); // construct Matrix (vector) type
//XXX test numpy array is coming through as C array and we can rw, checks OK
int i;
// for(i=0;i<Dn*Dm;++i) {
// printf("Address %x : ",(D+i));
// printf("was %f \t" , D[i]);
// D[i]+=1.0;
// printf("now: %f \n" , D[i]);
// }
// check that array D was copied to matrix ddata, and we can r/w
for(i=0;i<Dm*Dn;++i) {
printf("iter %d Address %x : ",i,ddata[i/Dm][i%Dm]);
printf("was %f \t" , ddata[i/Dm][i%Dm]);
ddata[i/Dm][i%Dm]+=1.0;
printf("now: %f \n" ,ddata[i/Dm][i%Dm]);
}
Gaumixmod::Gaumixmod(ddata,mmeans);
//return data from vector to ctypes array C so we can check data returns to python
//via numpy array, checks ok
for(i=0;i<Dm*Dn;++i) {
D[i] = ddata[i/Dm][i%Dm];
}
}
}
谢谢 有一个用于与C接口的新库,您可以查看它:
#include "nr3.h"
#include "cholesky.h"
#include "gaumixmod.h"
extern "C" {
void cGaumixmod(double* D, int Dm, int Dn, double* M, int Mm, int Mn) {
MatDoub ddata(Dm,Dn,*D); // construct Matrix (vector) type
MatDoub mmeans(Mm,Mn,*M); // construct Matrix (vector) type
//XXX test numpy array is coming through as C array and we can rw, checks OK
int i;
// for(i=0;i<Dn*Dm;++i) {
// printf("Address %x : ",(D+i));
// printf("was %f \t" , D[i]);
// D[i]+=1.0;
// printf("now: %f \n" , D[i]);
// }
// check that array D was copied to matrix ddata, and we can r/w
for(i=0;i<Dm*Dn;++i) {
printf("iter %d Address %x : ",i,ddata[i/Dm][i%Dm]);
printf("was %f \t" , ddata[i/Dm][i%Dm]);
ddata[i/Dm][i%Dm]+=1.0;
printf("now: %f \n" ,ddata[i/Dm][i%Dm]);
}
Gaumixmod::Gaumixmod(ddata,mmeans);
//return data from vector to ctypes array C so we can check data returns to python
//via numpy array, checks ok
for(i=0;i<Dm*Dn;++i) {
D[i] = ddata[i/Dm][i%Dm];
}
}
}
看看您的_gaumixmod.argtypes行。np.ctypeslib.ndpointer(dtype=np.float64,flags='C_continuous')真的是一种类型吗?我会尝试使用ctypes.POINTER(ctypes.c_double)来确定。因为“C_contract”与指针类型无关,因为它只指向内存中的某个位置。另一种情况可能更为可能_gaumixmod(D,…)正在寻找一个double*,您正在给它一个np.array。如果没有其他内容,它应该是D.ctypes.data_as(ctypes.POINTER(ctypes.c_double))您是否考虑过使用Cython?@K.Brafford,好建议。与尝试使用ctypes相比,这种方法更不容易出错。
#include "nr3.h"
#include "cholesky.h"
#include "gaumixmod.h"
extern "C" {
void cGaumixmod(double* D, int Dm, int Dn, double* M, int Mm, int Mn) {
MatDoub ddata(Dm,Dn,*D); // construct Matrix (vector) type
MatDoub mmeans(Mm,Mn,*M); // construct Matrix (vector) type
//XXX test numpy array is coming through as C array and we can rw, checks OK
int i;
// for(i=0;i<Dn*Dm;++i) {
// printf("Address %x : ",(D+i));
// printf("was %f \t" , D[i]);
// D[i]+=1.0;
// printf("now: %f \n" , D[i]);
// }
// check that array D was copied to matrix ddata, and we can r/w
for(i=0;i<Dm*Dn;++i) {
printf("iter %d Address %x : ",i,ddata[i/Dm][i%Dm]);
printf("was %f \t" , ddata[i/Dm][i%Dm]);
ddata[i/Dm][i%Dm]+=1.0;
printf("now: %f \n" ,ddata[i/Dm][i%Dm]);
}
Gaumixmod::Gaumixmod(ddata,mmeans);
//return data from vector to ctypes array C so we can check data returns to python
//via numpy array, checks ok
for(i=0;i<Dm*Dn;++i) {
D[i] = ddata[i/Dm][i%Dm];
}
}
}