summaryrefslogtreecommitdiff
path: root/pyuno
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2012-02-16 16:30:25 +0100
committerStephan Bergmann <sbergman@redhat.com>2012-02-16 16:30:58 +0100
commit1bb0d979b5ac5ed0cd831c6c8c0ab55dc2621eba (patch)
treec1a5b38f1b56f03e9ed8ce6d0fe86e36cc7cba33 /pyuno
parent5c714632583036f72377aa0fa6ed1137e53582dc (diff)
Adapt pyuno.so wrapper to Python 3 support
Diffstat (limited to 'pyuno')
-rw-r--r--pyuno/source/module/pyuno_dlopenwrapper.c76
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: */