Mailing List Archive

Embedding Python when using different calling conventions.
This is a bit yucky, but still a valid problem.

Malte Kroeger [kroeger@bigfoot.com] recently posted to python-help
with a problem. He has an existing Windows project that he wishes to
use Python in. This project does not use the standard __cdecl calling
convention that Python uses, for various reasons known only to him.
As it is an existing project and quite probably a large, complex one,
I am willing to accept that moving his existing project to match
Python's calling convention is not reasonable. I also feel for him,
as I have personally battled this - both with Python and with other
projects.

He has requested that Python explicitely declare the calling
convention it uses. Thus, it can be embedded in any project.

He wants a new macro. Eg:

DL_IMPORT(int) PyRun_SimpleFile Py_PROTO((FILE *, char *));
becomes
DL_IMPORT(int) CALLCONV PyRun_SimpleFile Py_PROTO((FILE *, char *));

I suggested embedding the calling convention in with the DL_IMPORT
macro, but he pointed out this macro is also used for variables, where
the convention syntax is illegal.

To my mind this is reasonable (maybe not the spelling, but definately
the intent). Any thoughts?

Mark.
Re: Embedding Python when using different calling conventions. [ In reply to ]
Mark Hammond wrote:
>
> This is a bit yucky, but still a valid problem.
>
> Malte Kroeger [kroeger@bigfoot.com] recently posted to python-help
> with a problem. He has an existing Windows project that he wishes to
> use Python in. This project does not use the standard __cdecl calling
> convention that Python uses, for various reasons known only to him.
> As it is an existing project and quite probably a large, complex one,
> I am willing to accept that moving his existing project to match
> Python's calling convention is not reasonable. I also feel for him,
> as I have personally battled this - both with Python and with other
> projects.

Isn't the default calling scheme selectable via compiler switches ?
I remember that this was the case with the IBM compiler on OS/2.

> He has requested that Python explicitely declare the calling
> convention it uses. Thus, it can be embedded in any project.
>
> He wants a new macro. Eg:
>
> DL_IMPORT(int) PyRun_SimpleFile Py_PROTO((FILE *, char *));
> becomes
> DL_IMPORT(int) CALLCONV PyRun_SimpleFile Py_PROTO((FILE *, char *));
>
> I suggested embedding the calling convention in with the DL_IMPORT
> macro, but he pointed out this macro is also used for variables, where
> the convention syntax is illegal.

Perhaps switching to DL_IMPORT_FUNCTION(int) for functions would be a
better idea. This would leave the previous definition of DL_IMPORT
untouched (which is used by a few extensions too).

OTOH, we could take chance to reorganize these macros from bottom
up: when I started coding extensions I found them not very useful
mostly because I didn't have control over them meaning "export
this symbol" or "import the symbol". Especially the DL_IMPORT
macro is strange because it seems to handle both import *and*
export depending on whether Python is compiled or not.

FYI, I'm using these macros for the mx extensions:

/*
Macros to control export and import of DLL symbols.

We use our own definitions since Python's don't allow specifying
both imported and exported symbols at the same time.

*/

/* Macro to "mark" a symbol for DLL export */

#if (defined(_MSC_VER) && _MSC_VER > 850 \
|| defined(__MINGW32__) || defined(__BEOS__))
# ifdef __cplusplus
# define MX_EXPORT(type) extern "C" type __declspec(dllexport)
# else
# define MX_EXPORT(type) extern type __declspec(dllexport)
# endif

#elif defined(__WATCOMC__)
# define MX_EXPORT(type) extern type __export

#else
# define MX_EXPORT(type) extern type
#endif

/* Macro to "mark" a symbol for DLL import */

#if defined(__BORLANDC__)
# define MX_IMPORT(type) extern type __import

#elif (defined(_MSC_VER) && _MSC_VER > 850 \
|| defined(__MINGW32__) || defined(__BEOS__))
# ifdef __cplusplus
# define MX_IMPORT(type) extern "C" type __declspec(dllimport)
# else
# define MX_IMPORT(type) extern type __declspec(dllimport)
# endif

#else
# define MX_IMPORT(type) extern type
#endif

plus these kind of defines in the extension header files:

#ifdef MX_BUILDING_MXDATETIME
# define MXDATETIME_EXTERNALIZE MX_EXPORT
#else
# define MXDATETIME_EXTERNALIZE MX_IMPORT
#endif

Note that MX_EXPORT always defines export symbols and MX_IMPORT
always means "import the symbol". The *_EXTERNALIZE macro decides
which form to take depending on whether the header file is used
to compile the extension itself or using the extension.

--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: 62 days left
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
Re: Embedding Python when using different calling conventions. [ In reply to ]
> OTOH, we could take chance to reorganize these macros from bottom
> up: when I started coding extensions I found them not very useful
> mostly because I didn't have control over them meaning "export
> this symbol" or "import the symbol". Especially the DL_IMPORT
> macro is strange because it seems to handle both import *and*
> export depending on whether Python is compiled or not.

This would be very nice. The DL_IMPORT/DL_EXPORT stuff is really weird unless
you're working with it all the time. We were trying to build a plugin DLL for
PythonWin and first you spend hours finding out that you have to set DL_IMPORT
(and how to set it), and the you spend another few hours before you realize
that you can't simply copy the DL_IMPORT and DL_EXPORT from, say, timemodule.c
because timemodule.c is going to be in the Python core (and hence can use
DL_IMPORT for its init() routine declaration) while your module is going to be
a plugin so it can't.

I would opt for a scheme where the define shows where the symbols is expected
to live (DL_CORE and DL_THISMODULE would be needed at least, but probably one
or two more for .h files).
--
Jack Jansen | ++++ stop the execution of Mumia Abu-Jamal ++++
Jack.Jansen@oratrix.com | ++++ if you agree copy these lines to your sig ++++
www.oratrix.nl/~jack | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm