Loading shared modules from an imbedded interpreter

M.-A. Lemburg mal at lemburg.com
Sun Aug 29 05:51:13 EDT 1999


Dave Wallace wrote:
> 
> Hello,
> 
>     I am attempting to embed Python in a c executable, unfortunately
> when I attempt to import a shared-c module or a Python module that
> imports a shared-c module, I get errors like:
> 
>   Traceback (innermost last):
>   File "<string>", line 1, in ?
> ImportError: /usr/local/lib/python1.5/lib-dynload/selectmodule.so:
> undefined symbol: _Py_NoneStruct
> 
> where the undefined symbol varies from file to file. Apparently, when
> compiling parts of libpython are left out since they are not referenced
> by my code. Is there any way to force them to be included?

You'll have to add an option to the linker flags used to link
Python. These of course vary depending on the linker used. For
GNU ld it is (copied from `man ld`):

       -E

       -export-dynamic
              When  creating  an ELF file, add all symbols to the
              dynamic symbol table.  Normally, the dynamic symbol
              table contains only symbols which are used by a dy­
              namic object.  This option is needed for some  uses
              of dlopen.

If that doesn't work, try to change this part in Python/importdl.c:

#ifdef RTLD_NOW
		/* RTLD_NOW: resolve externals now
		   (i.e. core dump now if some are missing) */
		void *handle = dlopen(pathname, RTLD_NOW);
#else
		void *handle;
		if (Py_VerboseFlag)
			printf("dlopen(\"%s\", %d);\n", pathname,
			       RTLD_LAZY);
		handle = dlopen(pathname, RTLD_LAZY);
#endif /* RTLD_NOW */
		if (handle == NULL) {
			PyErr_SetString(PyExc_ImportError, dlerror());
			return NULL;
		}
		if (fp != NULL && nhandles < 128)
			handles[nhandles++].handle = handle;
		p = (dl_funcptr) dlsym(handle, funcname);

...to the old version (pre 1.5.2):

#ifdef RTLD_NOW
		/* RTLD_NOW: resolve externals now
		   (i.e. core dump now if some are missing) */
		void *handle = dlopen(pathname, RTLD_NOW | RTLD_GLOBAL);
#else
		void *handle;
		if (Py_VerboseFlag)
			printf("dlopen(\"%s\", %d);\n", pathname,
			       RTLD_LAZY | RTLD_GLOBAL);
		handle = dlopen(pathname, RTLD_LAZY | RTLD_GLOBAL);
#endif /* RTLD_NOW */
		if (handle == NULL) {
			PyErr_SetString(PyExc_ImportError, dlerror());
			return NULL;
		}
		if (fp != NULL && nhandles < 128)
			handles[nhandles++].handle = handle;
		p = (dl_funcptr) dlsym(handle, funcname);

Note the use of the dlopen flag RTLD_GLOBAL. This flag was dropped
for 1.5.2 due to various platform dependent problems. Perhaps
we should readd the flag depending on a configure switch...

-- 
Marc-Andre Lemburg
______________________________________________________________________
Y2000:                                                   127 days left
Business:                                      http://www.lemburg.com/
Python Pages:                           http://www.lemburg.com/python/





More information about the Python-list mailing list