Yet another Numeric Swig core dump problem

Edward C. Jones edcjones at erols.com
Sat Aug 11 21:46:47 EDT 2001


Travis Oliphant wrote:
> Edward C. Jones wrote:
>> (code omitted)

> import_array must be in the file that is accessing the C-API for Numeric.
> 
> You are using PyArray_FromDims in a file without the import_array statement.
> 
> A quick hack is to place import_array in the KLTfeatures file.

I wrote a short essay about what I ended up doing. Something like this 
should be in the SWIG and Numeric documentation.
If
     Numeric and SWIG are used together in creating a Python extension
   and
     there are C/C++ files as part of the extension
then
   Numeric 20.1.0 will probably break your code.

This occurs because changes were made to arrayobject.h between Numeric 
20.0.0 and 20.1.0.

The changes that need to be made in your code are explained
by Konrad Hinsen
(http://www.geocrawler.com/archives/3/1329/2001/5/0/5718231/)
===================================================================
FROM: Konrad Hinsen
DATE: 05/09/2001 09:12:25
SUBJECT:  [Numpy-discussion] Modified header files

Recently we had a discussion about how to use NumPy arrays from
extension modules with multiple source files, on various
platforms.  The modified header files that are attached to this
message provide a (hopefully!) general solution. In fact, I
propose to make them part of the official distribution, unless
there are objections.

If used like before, these header files give exactly the same
result as the ones in NumPy 20.0.0. However, they permit to define
the name of the C API pointer array and make it globally visible.
Under the condition that the chosen name is unique, this should
not create problems under any platform, no matter if static or
dynamic linking is used.

To use NumPy features in multiple source file extension modules,
you have to write

#define PY_ARRAY_UNIQUE_SYMBOL PyArrayXXX
#include "Numeric/arrayobject.h"

in the main source file (the one that contains the init function)
and

#define PY_ARRAY_UNIQUE_SYMBOL PyArrayXXX
#define NO_IMPORT_ARRAY
#include "Numeric/arrayobject.h"

in all the others. The symbol you choose instead of PyArrayXXX
should contain both the name of the imported module (array) and
the name of the importing module (whatever your module is called)
in order to be unique with a reasonably high probability.

The same applies to the Ufunc module, just replace "array" by
"ufunc" in the example. I have also applied the "static"
correction to the Ufunc header file, there is no reason not to do
it.

Konrad.
-- 
-----------------------------------------------------------------------
Konrad Hinsen                            | E-Mail:
hinsen at NO-SPAM.cnrs-orleans.fr
Centre de Biophysique Moleculaire (CNRS) | Tel.: +33-2.38.25.56.24
Rue Charles Sadron                       | Fax:  +33-2.38.63.15.17
45071 Orleans Cedex 2                    | Deutsch/Esperanto/English/
France                                   | Nederlands/Francais
-----------------------------------------------------------------------
========================================================================

I do this by modifying one header file that is included in all
the ".c" and ".i" files. In the following example this header file
is "spam.h".

------------------------------------------------------------
doit.py:

#! /usr/bin/python

import Numeric, spam

spam.funct()
print 'spam.funct completed'
------------------------------------------------------------
spam.h:

#include "Python.h"
#define PY_ARRAY_UNIQUE_SYMBOL Py_Array_API_spam
#ifndef SWIG_FILE_WITH_INIT
#define NO_IMPORT_ARRAY
#endif

#include "/usr/include/python2.1/Numeric/arrayobject.h"
void funct(void);
------------------------------------------------------------
spam.i:

%module spam

%{
#define SWIG_FILE_WITH_INIT
#include "spam.h"
%}

%init %{
import_array();
printf("called import_array\n");
%}

void funct(void);
------------------------------------------------------------
spammodule.c

#include "spam.h"

void funct(void)
{
PyArrayObject *pao;
int dims[2];

dims[0] = 100;
dims[1] = 200;
printf("Calling PyArray_FromDims\n");
pao = (PyArrayObject*) PyArray_FromDims(2, dims, PyArray_UBYTE);
printf("Completed PyArray_FromDims\n");
Py_DECREF(pao);
}
------------------------------------------------------------
compile script:

swig -python spam.i
gcc -c -Wall spammodule.c spam_wrap.c -I/usr/include/python2.1
ld -shared spammodule.o spam_wrap.o -o spam.so
------------------------------------------------------------

I use RedHat 7.1 Linux on a PC, Python 2.1, Numeric 20.1.0, SWIG 1.1 
build 883, and gcc 2.96.


> A better way is to use some defines appropriately as described by Paul 
> Dubois (I'm not sure exactly how to do it).  











More information about the Python-list mailing list