Python/C API: using from a shared library

Robie Basak robie at justgohome.co.uk
Tue Nov 25 04:32:26 EST 2008


Hi,

If I use dlopen() to open a shared library that I've written, and that
shared library tries to use the Python/C API, then it fails. I've
reduced the problem to the test case below. The error is:

ImportError: /usr/lib/python2.5/lib-dynload/time.so: undefined symbol:
PyExc_ValueError

It appears that time.so tries to resolve PyExc_ValueError out of my
program instead of libpython.so.

I'm using Ubuntu 8.04, so that's Python 2.5.2.

How do I go about getting this to work? Is this a bug in lib-dynload, or
am I using the wrong linker flags?

Would this be better asked in python-dev?

Thanks,

Robie

/* Start of mylib.c */

/* Compile with: gcc -I/usr/include/python2.5 -fno-strict-aliasing -g -fwrapv -Wall -Wstrict-prototypes -L/usr/lib/python2.5/config -fPIC -shared -l:libpython2.5.so.1 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions -o mylib.so mylib.c */

#include <Python.h>
#include <stdio.h>

int init(void) {
    PyObject *module;

    module = PyImport_ImportModule("time");
    if(!module) {
	fprintf(stderr, "python module load failed\n");
	PyErr_Print();
	return -1;
    }

    Py_DECREF(module);

    return 0;
}

void init_module(void) {
    fprintf(stderr, "python initalizing\n");
    Py_Initialize();
    fprintf(stderr, "python initialized\n");
}

/* vim: set ts=8 sts=4 sw=4 ai : */

/* End of mylib.c */

/* Start of myprog.c */
/* Compile with: gcc -o myprog -ldl myprog.c */

#include <dlfcn.h>
#include <stdio.h>

int main(int argc, char **argv) {
    void *lib;
    int (*init)(void);
    void (*init_module)(void);
    char *error;

    lib = dlopen("./mylib.so", RTLD_LAZY);
    if(!lib) {
	fprintf(stderr, "%s\n", dlerror());
	return 1;
    }
    dlerror();

    *(void **) (&init_module) = dlsym(lib, "init_module");
    if((error=dlerror()) != NULL) {
	fprintf(stderr, "%s\n", error);
	return 1;
    }
    (*init_module)();

    *(void **) (&init) = dlsym(lib, "init");
    if((error=dlerror()) != NULL) {
	fprintf(stderr, "%s\n", error);
	return 1;
    }
    (*init)();
    dlclose(lib);
    return 0;
}

/* vim: set ts=8 sw=4 sts=4 ai : */

/* End of myprog.c */



More information about the Python-list mailing list