Using dynamic libraries with Python C extensions in embedded Python apps fails

Bob Hepple bob_hepple at yahoo.com
Thu Feb 20 11:47:11 CET 2003


Yes - I'm trying to do just about everything at once here!

I have a Python extension module written in C. I want to use it as a
python
extension both in python scripts and in an embedded C app.

The module foobar lives in /usr/lib/python1.5/site-packages/foobar.so
and is
built by setup.py in the usual way from foobar.c and a -l linker
reference
to libfoobar.so which itself lives in /usr/local/lib:

running install
running build
running build_ext
building 'foobar' extension
gcc -g -O2 -fPIC -I/usr/local/include -I/usr/include/python1.5 -c
foobar.c -o build/temp.linux-i686-1.5/foobar.o
gcc -shared build/temp.linux-i686-1.5/foobar.o -L/usr/local/lib
-lfoobar -o build/lib.linux-i686-1.5/foobar.so
running install_lib
copying build/lib.linux-i686-1.5/foobar.so ->
/usr/lib/python1.5/site-packages

It runs fine when called from python:

#!/usr/bin/python
import foobar
foobar_init()

All seems peachy. 

However when I try to call the foobar extension from an embedded
python
interpreter, the PyImport_Import() method fails:

#include <Python.h>
...
    Py_Initialize();
    pName = PyString_FromString("foobar");
	if (!pName) {
		retval = CKR_GENERAL_ERROR;
		goto exit_point;
	}

    pModule = PyImport_Import(pName);
	... returns NULL

I tried PyImport_ImportModule("foobar") too with the same result.

The initfoobar() method in the extension module never gets called (I
put
a printf call there to check). There are no error messages from ld or
python.

If I run 'strace' on the embedded version, I can see something
(presumably dlopen()) opening the extension module and (presumably a
linker) opening the shared library: ...

open("/usr/lib/python1.5/site-packages/foobar.so", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0775, st_size=111607, ...}) = 0
open("/usr/lib/python1.5/site-packages/foobar.so", O_RDONLY) = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0@\23\0\000"...,
1024) = 1024
...
close(4)                                = 0
open("/usr/local/lib/libfoobar.so", O_RDONLY) = 4
read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360d\1"...,
1024) = 1024
fstat64(4, {st_mode=S_IFREG|0775, st_size=2204306, ...}) = 0

Oddly, the foobar extension package is opened twice - presumably the
first time it is loading the modules and the second time it is the
linker trying to resolve externals. These are actually resolved later
when /usr/local/lib/libfoobar.so is opened.

Puzzling, to say the least? Any ideas out there?

Background - Linux RedHat 7.3 / python 1.5 (2.2 makes no difference)

TIA




More information about the Python-list mailing list