c++ - Python Ctypes 崩溃调用 C++ 函数的 C 包装器

标签 c++ python c segmentation-fault ctypes

我正在尝试使用 Python Ctypes 来连接已发布的(闭源)C++ 库。我(尝试)编写了一个基本的 C 风格函数包装器来构造 C++ vector 风格对象并调用 C++ 例程。我还(尝试)编写了一个基本的 python 脚本来加载共享库。除了调用 C++ 例程的行外,一切正常:

*** glibc detected *** python: free(): invalid next size (fast): 0x0000000001e73c00 ***

这是文件,不幸的是我不能分享标题,但如果需要我可以写一些类似的东西......

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


  }

}

goumixmod.py:

import platform,ctypes
import numpy as np


# ------------------------------------------------------------------------
# define correct library from platfrom, assuming 64bit for linux machines   
# ------------------------------------------------------------------------  

if platform.system()=='Microsoft':
    raise Exception('MS not supported.')
elif platform.system()=='Darwin':
    libgaumixmod = ctypes.cdll.LoadLibrary("./gaumixmod.so")
elif platform.system()=='Linux':
    libgaumixmod = ctypes.cdll.LoadLibrary("./gaumixmod.so")
else:
    #hope for the best                                                      
    libgaumixmod = ctypes.cdll.LoadLibrary("./gaumixmod.so")

# --------------------------------------------------
# define SafeCall                                                           
#---------------------------------------------------                                  

def SafeCall(ret):
    """pass, code l8r""
    print ret
#---------------------------------------------------  
# define arg types and res types of function                                
# -----------------------------------------------------------------------             
_gaumixmod = libgaumixmod.cGaumixmod
_gaumixmod.restype = ctypes.c_int
_gaumixmod.argtypes = [np.ctypeslib.ndpointer(dtype=np.float64,flags='C_CONTIGUOUS'),
            ctypes.c_int,
            ctypes.c_int,
            np.ctypeslib.ndpointer(dtype=np.float64,flags='C_CONTIGUOUS'),
            ctypes.c_int,
            ctypes.c_int]


def gaumixmod(D,K):
    """Python binding for C++ guassian mixure model code."""

    ret = _gaumixmod(D,D.shape[0],D.shape[1],K,K.shape[0],K.shape[1])
    SafeCall(ret)
    return D,K

D = np.ones((100,100)).astype(np.float64)
K = np.ones((4,1)).astype(np.float64)

print gaumixmod(D,K)

我用以下代码编译了这个爵士乐:

g++ -fPIC -c gaumixmod.cpp;
g++ -shared -o gaumixmod.so gaumixmod.o

然后运行

python gaumixmod.py

我的研究表明这个错误类似于 segFault,其中 python 试图访问其范围之外的内存...这是我不理解的部分,因为注释掉了 C++ 行 Gaumixmod::Gaumixmod() ,一切正常,并且该例程应该在 cGaumixmod() 函数中实例化的 vector 上运行,而不是 python numpy 数组。我对 C++ 真的很陌生,虽然我已经多次使用 C 类型来创建 C 库。我希望有一些 C++、python 和 ctypes 经验的人可以在这里提供一些见解/指导。

谢谢!

最佳答案

有一个用于与 C 接口(interface)的新库,您可能会看它:

http://cffi.readthedocs.org/en/latest/index.html

关于c++ - Python Ctypes 崩溃调用 C++ 函数的 C 包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11056978/

相关文章:

C++ static constexpr 成员在类外重新声明

c++ - Const 仍然允许在运算符函数 c++ 下进行更改

python - Pandas 数据框选择

python - 从两个集合的字典中的另一个集合中删除给定元素

c++ 如何使用 protected 赋值运算符进行赋值?

C++在Windows中更改规范模式

python - matplotlib 对 x Axis 的值进行分组

c - c中相同数据类型的多个数组的通用函数?

c - 如何找到stack smash的原因

c - 使用 Visual Studio 2008/Visual C++ 2008 Express 学习 C