
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/