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.
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/
participants (2)
-
M.-A. Lemburg
-
Mark Hammond