Python中的C(cpp)扩展在一台机器上工作,但在另一台机器上不工作

Python中的C(cpp)扩展在一台机器上工作,但在另一台机器上不工作,python,Python,很抱歉,如果这个问题有点模糊,可能根本不适合stackoverflow,但我只是想试一试,也许有人会知道原因是什么,或者给出测试方法,问题在哪里 我有一个C(cpp?)扩展,它在我的13.04 Lubuntu和gcc 4.7.3、python 2.7.4、numpy 1.7.1上运行良好,但在另一台机器上的12.04 Ubuntu和gcc 4.6.3、python 2.7.3、numpy 1.6.1上无法运行。它的构建/安装似乎很好,但当我实际尝试运行它时,它会给我一个特定的错误: TypeEr

很抱歉,如果这个问题有点模糊,可能根本不适合stackoverflow,但我只是想试一试,也许有人会知道原因是什么,或者给出测试方法,问题在哪里

我有一个C(cpp?)扩展,它在我的13.04 Lubuntu和gcc 4.7.3、python 2.7.4、numpy 1.7.1上运行良好,但在另一台机器上的12.04 Ubuntu和gcc 4.6.3、python 2.7.3、numpy 1.6.1上无法运行。它的构建/安装似乎很好,但当我实际尝试运行它时,它会给我一个特定的错误:

TypeError: Array type 7 didn't match expected type -1
我不想用构建代码向您发送垃圾邮件,但我将包括这两个代码,我认为它们是主要的。首先是cpp文件

    #define PY_ARRAY_UNIQUE_SYMBOL j_sad_pyarray
    #include "Common/JAssert.h"
    #include "Python.h"
    #include "numpy/arrayobject.h"
    #include "Common/JPythonCommon.h"

    extern "C" PyObject *sad_correlation(PyObject *self, PyObject *args)
    {
        // inputs
        PyArrayObject *a, *b;       // list of coordinates for the input polygons (2d double numpy array)

        // parse the input arrays from *args
        if (!PyArg_ParseTuple(args, "O!O!", 
                &PyArray_Type, &a, 
                &PyArray_Type, &b))
        {
            PyErr_Format(PyErr_NewException((char*)"exceptions.TypeError", NULL, NULL), "Unable to parse array!");
            return NULL;
        }

        // We expect a and b to be two-dimensional double arrays.
        // The following constructors will check those requirements
        JPythonArray2D<double> window1(a);
        JPythonArray2D<double> window2(b);
        if (PyErr_Occurred()) return NULL;

    //  ALWAYS_ASSERT(window1.NDims() == 2);
    //  ALWAYS_ASSERT(window2.NDims() == 2);
        if ((window1.NDims() != 2) || (window1.NDims() != 2))
        {
            PyErr_Format(PyErr_NewException((char*)"exceptions.TypeError", NULL, NULL), "Expected two 2D arrays as parameters");
            return NULL;
        }

        int maxDX = window2.Dims()[0] - window1.Dims()[0];
        int maxDY = window2.Dims()[1] - window1.Dims()[1];
    //  ALWAYS_ASSERT(maxDX >= 0);
    //  ALWAYS_ASSERT(maxDY >= 0);
        if ((maxDX < 0) || (maxDY < 0))
        {
            PyErr_Format(PyErr_NewException((char*)"exceptions.TypeError", NULL, NULL), "Expected second array to be bigger than or equal to first array");
            return NULL;
        }

        npy_intp output_dims[2] = { maxDX+1, maxDY+1 };
        PyArrayObject *result = (PyArrayObject *)PyArray_SimpleNew(2, output_dims, NPY_DOUBLE);
        JPythonArray2D<double> resultArray(result);

        // For every possible shift of 'a' relative to 'b', calculate the SAD
    //  printf("Array sizes %ldx%ld, %ldx%ld\n", window1.Dims()[0], window1.Dims()[1], window2.Dims()[0], window2.Dims()[1]);
        int w1Width = window1.Dims()[0];
        int w1Height = window1.Dims()[1];
        for (int dy = 0; dy <= maxDY; dy++)
            for (int dx = 0; dx <= maxDX; dx++)
            {
                int sad = 0;
                for (int y = 0; y < w1Height; y++)
                    for (int x = 0; x < w1Width; x++)
                    {
                        // ***** is this the correct way round?
                        ALWAYS_ASSERT(window1[0].Dims()[0] == window1.Dims()[1]);
                        sad += abs(window1[x][y] - window2[x+dx][y+dy]);
                    }
                resultArray[dx][dy] = sad;  
    //          printf("Result[%d][%d] = %d\n", dx, dy, sad);       
            }
        return PyArray_Return(result);
    }


    /* Define a methods table for the module */

    static PyMethodDef corr_methods[] = {
        {"sad_correlation", sad_correlation, METH_VARARGS}, 
        {NULL,NULL} };



    /* initialisation - register the methods with the Python interpreter */

    extern "C" void initj_py_sad_correlation(void)
    {
        (void) Py_InitModule("j_py_sad_correlation", corr_methods);
        import_array();
    }
我无法在这台机器上更新gcc(无论我做什么,我最终都是同一台),您认为这可能是一个问题吗(即gcc版本)?有什么方法可以追踪这个问题吗

JPythonArray.h的部分:

template<class Type> class JPythonArray1D : public JPythonArray<Type>
{
  public:
    JPythonArray1D(PyArrayObject *init) : JPythonArray<Type>(init, 1) { }
    JPythonArray1D(PyObject *init) : JPythonArray<Type>(init, 1) { }
    JPythonArray1D(Type *inData, npy_intp *inDims, npy_intp *inStrides) : JPythonArray<Type>(inData, 1, inDims, inStrides) { }

    Type &operator[](int i)     // Note we return a reference here, so that this can be used as an lvalue, e.g. my1DArray[0] = 1.0, or my2DArray[0][0] = 1.0;
    {
//      printf("Access element %d of %d\n", i, JPythonArray<Type>::dims[0]);
        ALWAYS_ASSERT(i < JPythonArray<Type>::dims[0]);
        return JPythonArray<Type>::data[i * JPythonArray<Type>::strides[0]];
    }

    Type &GetIndex_CanPromote(int i)
    {
        // Behaves like operator[], but if we have a single value in the array then returns that value regardless of i
        // This isn't ideal - it's a way of working around the fact that the object used to initialize this array may be a scalar value
        if (JPythonArray<Type>::dims[0] == 1)
            return JPythonArray<Type>::data[0];
        else
            return operator[](i);
    }
};

template<class Type> class JPythonArray2D : public JPythonArray<Type>
{
  public:
    JPythonArray2D(PyArrayObject *init) : JPythonArray<Type>(init, 2) { }
    JPythonArray2D(PyObject *init) : JPythonArray<Type>(init, 2) { }
    JPythonArray2D(Type *inData, npy_intp *inDims, npy_intp *inStrides) : JPythonArray<Type>(inData, 2, inDims, inStrides) { }

    JPythonArray1D<Type> operator[](int i)
    {
        // Could check that i is in range (check against dims[0])
        return JPythonArray1D<Type>(JPythonArray<Type>::data + JPythonArray<Type>::strides[0] * i, JPythonArray<Type>::dims + 1, JPythonArray<Type>::strides + 1);
    }
};

template<class Type> class JPythonArray3D : public JPythonArray<Type>
{
  public:
    JPythonArray3D(PyArrayObject *init) : JPythonArray<Type>(init, 3) { }
    JPythonArray3D(PyObject *init) : JPythonArray<Type>(init, 3) { }

    JPythonArray2D<Type> operator[](int i)
    {
        // Could check that i is in range (check against dims[0])
        return JPythonArray2D<Type>(JPythonArray<Type>::data + JPythonArray<Type>::strides[0] * i, JPythonArray<Type>::dims + 1, JPythonArray<Type>::strides + 1);
    }
};

template<class Type> JPythonArray2D<Type> PromoteTo2D(PyArrayObject *init)
{
    if (PyArray_NDIM(init) == 1)
    {
        npy_intp dims[2] = { 1, PyArray_DIMS(init)[0] };
        npy_intp strides[2] = { 0, PyArray_STRIDES(init)[0] / sizeof(Type) };
        return JPythonArray2D<Type>((Type *)PyArray_DATA(init), dims, strides);
    }
    else
    {
        // This could fail (if for example we are given a 3D array), but if that happens then a suitable error should be reported
        return JPythonArray2D<Type>(init);
    }
}
模板类JPythonArray 1d:public JPythonArray
{
公众:
JPythonArray1D(PyArrayObject*init):JPythonArray(init,1){
JPythonArray1D(PyObject*init):JPythonArray(init,1){}
JPythonArray1D(类型*inData,npy_intp*inDims,npy_intp*inStrides):JPythonArray(inData,1,inDims,inStrides){}
Type&operator[](int i)//注意,我们在这里返回一个引用,因此它可以用作左值,例如my1DArray[0]=1.0或my2DArray[0][0]=1.0;
{
//printf(“访问元素%d,共%d\n”,i,JPythonArray::dims[0]);
总是断言(i
以及完整的JPythonArray.cpp:

#include "JPythonArray.h"

template<> int ArrayType<double>(void) { return NPY_DOUBLE; }
template<> int ArrayType<float>(void) { return NPY_FLOAT; }
template<> int ArrayType<int>(void) { return NPY_INT; }
#包括“JPythonArray.h”
模板int数组类型(void){return NPY_DOUBLE;}
模板int数组类型(void){return NPY_FLOAT;}
模板int数组类型(void){return NPY_int;}

<代码>你在两台机器上都使用相同的Python和NoMPy版本吗?我可能错了,但是你似乎在C++代码>外部的“C”< /Cuth>块中使用C++语法(模板语法)。不知道这是不是个好主意。(您首先是如何构建扩展的?)。我编辑了这个问题,但也将它复制到了这里:13.04 Lubuntu和GCC4.7.3、python 2.7.4、Numpy1.7.1,但在12.04 Ubuntu和GCC4.6.3、python 2.7.3、Numpy1.6.1的另一台机器上不起作用。我只运行以下命令:python setup.py build;python setup.py安装并有一个文件夹构建,与.cpp和.h文件共用…但我怀疑这是你问我如何构建扩展的问题。你应该能够看到在运行
setup.py build
时是否使用了gcc或g++。此外,是<代码> JPythNalay2D2>代码>确实是一个C++模板?每当我得到一个错误(如果我修改了什么),它就说是GCC错误。否则,它在运行时不会显示在任何位置。有趣的是,我只有JPythonArray.h和.cpp,但在其中他们提到了JPythonArray2D(我不熟悉cpp,我是由其他人编写的代码,我在原始问题中添加了.h文件中可能相关的部分)。你认为代码是问题所在吗(即C、cpp问题?)我想知道为什么它在我的另一台机器上工作得很好。。。
#include "JPythonArray.h"

template<> int ArrayType<double>(void) { return NPY_DOUBLE; }
template<> int ArrayType<float>(void) { return NPY_FLOAT; }
template<> int ArrayType<int>(void) { return NPY_INT; }