problems with compiling and loading C++ extension

F

Faheem Mitha

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 = arr_dimensions;
strides = arr_strides/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;
}
********************************************************************************
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top