[Python-Dev] future-proofing vector tables for python APIs: binary-module interoperability
Luke Kenneth Casson Leighton
lkcl at lkcl.net
Sun Jan 25 18:34:42 CET 2009
On Sun, Jan 25, 2009 at 3:55 PM, Roumen Petrov
<bugtrack at roumenpetrov.info> wrote:
> Luke Kenneth Casson Leighton wrote:
>>>>
>>>> [SNIP]
>>>> Yes it is enough to encapsulate memory allocation and file functions
>>>> into
>>>> python shared library. The python provide memory allocation functions,
>>>> but
>>>> not all modules use them. File functions are hiden by posixmodule and
>>>> python
>>>> modules can't use them.
>>>
>>> except ... posixmodule gets renamed to ntmodule .... oh, i see what
>>> you mean: python modules aren't allowed _direct_ access to msvcrtNN's
>>> file functions, they have to go via posixmodule-renamed-to-ntmodule.
>>
>> .... thinking about this some more... posixmodule.c is linked (by
>> default) into pythonNN.dll, thus making pythonNN.dll totally dependent
>> on a version of msvcrt.
>
> This is not problem. If python*.dll hide msvcrt and other modules depend
> directly from python*.dll I expect issue to be resolved. i.e. python*.dll to
> be "portable runtime interface".
yehhhh :)
well - it looks like i am having success with removing all references
to data e.g. Py_NoneStruct, all of the PyExc_*Warning and
PyExc_*Error, all of the Py*_Types and more.
i'm making sure that macros are heavily used - so that on systems
where data _can_ be accessed through dynamic shared objects, it's done
so.
#if defined(MS_WINDOWS) || defined(__MINGW32__)
/* Define macros for conveniently creating "getter" functions,
* to avoid restrictions on dlls being unable to access data.
* see #5056
*/
/* use these for data that is already a pointer */
#define PyAPI_GETHDR(type, obj) \
PyAPI_FUNC(type) _Py_Get_##obj(void);
#define PyAPI_GETIMPL(type, obj) \
PyAPI_FUNC(type) _Py_Get_##obj(void) { return (type)obj; }
#define _PYGET(obj) _Py_Get_##obj()
/* use these for data where a pointer (&) to the object is returned
* e.g. no longer #define Py_None (&Py_NoneStruct) but
* #define Py_None _PTGETPTR(Py_NoneStruct)
*/
#define PyAPI_GETHDRPTR(type, obj) \
PyAPI_FUNC(type) _Py_Get_##obj(void);
#define PyAPI_GETIMPLPTR(type, obj) \
PyAPI_FUNC(type) _Py_Get_##obj(void) { return (type)&obj; }
#define _PYGETPTR(obj) _Py_Get_##obj()
#else
/* on systems where data can be accessed directly in shared modules,
* as an optimisation, return the object itself, directly.
*/
#define PyAPI_GETFNIMPL(obj) ;
#define PyAPI_GETHDR(type, obj) ;
#define PyAPI_GETIMPL(type, obj) ;
#define PyAPI_GETIMPLPTR(type, obj) ;
#define _PYGET(obj) (obj)
#define _PYGETPTR(obj) (&obj)
#endif /* defined(MS_WINDOWS) || defined(__MINGW32__)*/
as you can see from the Py_None example, on non-dll-based systems, you
get... wow, a macro which returns... exactly what was returned before.
zero impact.
on windows, you end up defining, creating and using a "getter"
function. two types. one which returns the object, the other returns
a pointer to the object.
l.
More information about the Python-Dev
mailing list