problems with compiling and loading C++ extension

Faheem Mitha faheem at email.unc.edu
Thu Apr 8 11:52:31 EDT 2004


Dear People,

I have been having an odd problem with compiling and loading a simple
C++ extension to python (as a .so file in Linux). Unfortunately, I'll
need to include my files in here so I apologize in advance for the
length of this message.

You can download also the files below from
http://www.stat.unc.edu/students/faheem/python/python.tar.gz in case
that is more convenient.

This needs blitz++ and python's distutils and numarray to compile.

When I try to load arrmod.so into python I get

In [1]: import arrmod
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call
last)

/tmp/wc/corrmodel/ex/<console>

ImportError: ./arrmod.so: undefined symbol:
_Z11py_to_blitzIdLi2EEN5blitz5ArrayIT_XT0_EEEP13PyArrayObject

If I move the py_to_blitz routine from conv.cc back into arrmod.cc,
the error disappears, arrmod loads in python, and everything works
correctly. I'm not sure what is going on here. Can someone enlighten
me? At first I thought it might have to do with the need for C
linkage, but I tried that, and it does not appear to be the case.

I also got the following compilation warning, which I don't
understand. I don't know if that is relevant.

---------------------------------------------------------------------
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -O3 -Wall
-Wstrict-prototypes -fPIC -I/usr/include/python2.3 -c conv.cc -o
/tmp/temp.linux-i686-2.3/conv.o -Wall
/usr/include/python2.3/Numeric/arrayobject.h:286: warning:
`void**PyArray_API'
   defined but not used
---------------------------------------------------------------------

Thanks in advance for any enlightenment.

                                                 Faheem.

**********************************************************************
Makefile
**********************************************************************
arrmod.so: arrmod.cc common.hh conv.cc
	python setup.py build --build-base=/tmp --build-lib=.
# may not do the right thing for everyone
clean:
	rm arrmod.so
	rm -r /tmp/temp.linux-i686-2.3
**********************************************************************

**********************************************************************
setup.py
**********************************************************************
from distutils.core import setup, Extension

module4 = Extension('arrmod',
                    sources = ['arrmod.cc','conv.cc'],libraries=["blitz","m"],
                    extra_compile_args = ['-Wall'])

setup (name = 'arrmod',
       version = '1.0',
       description = 'This module performs different operations on arrays',
       ext_modules = [module4]
       )
**********************************************************************

**********************************************************************
common.hh
**********************************************************************
#include "Python.h"
#include "Numeric/arrayobject.h"
#include <blitz/array.h>

using namespace std;
using namespace blitz;

template<class T, int N>
static Array<T,N> py_to_blitz(PyArrayObject* arr_obj);
**********************************************************************

**********************************************************************
conv.cc
**********************************************************************
#include "common.hh"

// Convert a Numpy array to a blitz one, using the original's data (no
// copy)
template<class T, int N>
static Array<T,N> py_to_blitz(PyArrayObject* arr_obj)
{
  int T_size = sizeof(T);
  TinyVector<int,N> shape(0);
  TinyVector<int,N> strides(0);
  int *arr_dimensions = arr_obj->dimensions;
  int *arr_strides = arr_obj->strides;

  for (int i=0;i<N;++i)
    {
      shape[i]   = arr_dimensions[i];
      strides[i] = arr_strides[i]/T_size;
    }
  return Array<T,N>((T*) arr_obj->data,shape,strides,neverDeleteData);
}
************************************************************************

************************************************************************
arrmod.cc
************************************************************************
#include "common.hh"

template<class T, int N>
static Array<T,N> py_to_blitz(PyArrayObject* arr_obj);

static PyObject * arrmod_elem(PyObject *self, PyObject *args);

static PyMethodDef arrmod_methods[] =
  {
    {"elem", (PyCFunction)arrmod_elem, METH_VARARGS, "Returns the trace of a two-dimensional array.\n"},
    {NULL, NULL, 0, NULL}
  };

PyMODINIT_FUNC initarrmod(void)
{
  (void) Py_InitModule3("arrmod", arrmod_methods, "Returns the Trace of a two-dimensional array.\n");
  import_array();
}

static PyObject * arrmod_elem(PyObject *self, PyObject *args)
{
  PyObject *input, *result;
  PyArrayObject *array;
  double el;
  int i, j;

  if (!PyArg_ParseTuple(args, "Oii", &input, &i, &j))
    return NULL;
  array = (PyArrayObject *)
    PyArray_ContiguousFromObject(input, PyArray_DOUBLE, 2, 2);
  if (array == NULL)
    return NULL;

  Array<double,2> arr = py_to_blitz<double,2>(array);

  el = arr(i,j);
  result = Py_BuildValue("d",el);
  return result;
}
********************************************************************************




More information about the Python-list mailing list