diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2012-02-16 16:30:25 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2012-02-16 16:30:58 +0100 |
commit | 1bb0d979b5ac5ed0cd831c6c8c0ab55dc2621eba (patch) | |
tree | c1a5b38f1b56f03e9ed8ce6d0fe86e36cc7cba33 /pyuno | |
parent | 5c714632583036f72377aa0fa6ed1137e53582dc (diff) |
Adapt pyuno.so wrapper to Python 3 support
Diffstat (limited to 'pyuno')
-rw-r--r-- | pyuno/source/module/pyuno_dlopenwrapper.c | 76 |
1 files changed, 55 insertions, 21 deletions
diff --git a/pyuno/source/module/pyuno_dlopenwrapper.c b/pyuno/source/module/pyuno_dlopenwrapper.c index 1ace0442ced6..487665b75700 100644 --- a/pyuno/source/module/pyuno_dlopenwrapper.c +++ b/pyuno/source/module/pyuno_dlopenwrapper.c @@ -26,38 +26,72 @@ * ************************************************************************/ -#include <rtl/string.h> +#include "sal/config.h" #include <stdlib.h> #include <string.h> -#ifdef LINUX -# ifndef __USE_GNU -# define __USE_GNU -# endif +#if defined LINUX && !defined __USE_GNU +#define __USE_GNU #endif #include <dlfcn.h> -void initpyuno () -{ - Dl_info dl_info; - void (*func)(void); +#include "Python.h" + +#include "rtl/string.h" - if (dladdr((void*)&initpyuno, &dl_info) != 0) { - void* h = 0; - size_t len = strrchr(dl_info.dli_fname, '/') - dl_info.dli_fname + 1; - char* libname = malloc(len + RTL_CONSTASCII_LENGTH( SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION ) + 1); - strncpy(libname, dl_info.dli_fname, len); - strcpy(libname + (len), SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION); +/* A wrapper around libpyuno.so, making sure the latter is loaded RTLD_GLOBAL + so that C++ exception handling works with old GCC versions (that determine + RTTI identity by comparing string addresses rather than string content). +*/ - h = dlopen (libname, RTLD_NOW | RTLD_GLOBAL); +static void * load(void * address, char const * symbol) { + Dl_info dl_info; + char * slash; + size_t len; + char * libname; + void * h; + void * func; + if (dladdr(address, &dl_info) == 0) { + abort(); + } + slash = strrchr(dl_info.dli_fname, '/'); + if (slash == NULL) { + abort(); + } + len = slash - dl_info.dli_fname + 1; + libname = malloc( + len + RTL_CONSTASCII_LENGTH(SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION) + + 1); + if (libname == 0) { + abort(); + } + strncpy(libname, dl_info.dli_fname, len); + strcpy(libname + len, SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION); + h = dlopen(libname, RTLD_NOW | RTLD_GLOBAL); free(libname); - if( h ) - { - func = (void (*)())dlsym (h, "initpyuno"); - (func) (); - } + if (h == NULL) { + abort(); } + func = dlsym(h, symbol); + if (func == NULL) { + abort(); + } + return func; } +#if PY_MAJOR_VERSION >= 3 + +PyObject * PyInit_pyuno(void) { + ((PyObject * (*)(void)) load((void *) &PyInit_pyuno, "PyInit_pyuno"))(); +} + +#else + +void initpyuno(void) { + ((void (*)(void)) load((void *) &initpyuno, "initpyuno"))(); +} + +#endif + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |