[Patches] Extension building on Win32 using Gnu C

Rene Liebscher R.Liebscher@gmx.de
Wed, 14 Jun 2000 13:41:24 +0200


This is a multi-part message in MIME format.
--------------149A4E4C425D8C885F0B8B92
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Greg Ward wrote:
> 
> > --- python.patched/dist/src/Include/object.h  Tue May 30 10:34:33 2000
> [...]
> > --- 107,120 ----
> >       PyObject_HEAD \
> >       int ob_size; /* Number of items in variable part */
> >
> > ! typedef DL_CLASSIMPORT_BEG struct _object {
> >       PyObject_HEAD
> > ! } DL_CLASSIMPORT_END PyObject;
> >
> >
> > + typedef DL_CLASSIMPORT_BEG struct {
> > +     PyObject_VAR_HEAD
> > + } DL_CLASSIMPORT_END PyVarObject;
> 
> This strikes me as really weird style.  Do those macros really *have* to
> be wormed into the typedefs in that way?  Isn't there a cleaner way to
> do it?

The Gnu-C compilers need these imports, there are two ways to do so

struct name { ... } __declspec(dllimport);

or 

struct __declspec(dllimport) name { ... };

Read also 
http://gcc.gnu.org/onlinedocs/gcc_4.html#SEC95  (paragraphs 3 and 4)
__declspec is another name for __attribute 
They don't mention dllimport and types in the same context, I don't know
why.
(However, MS Visual C++ uses the same import statements for imports of
classes from dll's. egcs 1.1.x uses __declspec() in MS compatible way.)

In typedefs you could have unnamed structs, so I prefer the second.
Even if it seems to work to have such a definition:
typedef struct __declspec(import) { ... } name;

If you don't have these imports in C-mode you get warnings and in C++
mode the compiler chrashs.
Perhaps it would be useful to reduce it to a 
"#define DL_IMPORT_TYPE __decspec(dllimport)"
instead of these two. (The attached patch realizes this idea, 
if you don't like the name replace it directly in the patch file.)

( I found this DL_CLASSIMPORT stuff (the only part of the patch
I didn't found for myself) at the following website
 http://starship.python.net/crew/kernr/mingw32/Notes.html
and I took it almost unchanged.)
 
> And do these macros have to be used in extensions as well?  Eg. if foo.c
> supplies an extension foo, so is compiled/linked to foo.pyd (a DLL in
> disguise), do I have to scatter foo.c with DL_CLASSIMPORT_{BEG,END} tags
> to make it compile with Cygwin?
No, you only need it, if these types are used in the interface of a dll 
you want to use (in this case you want to use python??.dll or should I
better say, link against its import library libpython??.a ) 
(You probably had to use it in your file foo.h if you 
want let other people use your extension dll on a direct way. Which also
means these people would need to link their modules against your dll.)


kind regards

Rene Liebscher
--------------149A4E4C425D8C885F0B8B92
Content-Type: text/plain; charset=us-ascii;
 name="python_new.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="python_new.patch"

diff -BcrN --minimal python/dist/src/Include/Python.h python.patched/dist/src/Include/Python.h
*** python/dist/src/Include/Python.h	Sun May 28 22:29:48 2000
--- python.patched/dist/src/Include/Python.h	Wed Jun 14 12:45:18 2000
***************
*** 46,51 ****
--- 46,59 ----
  #define DL_EXPORT(RTYPE) RTYPE
  #endif
  
+ /* The next is used by the Gnu C-compilers on Win32, for all others
+    it will be defined as empty */ 
+ /* Definition of every type, variables of which may be imported from DLL,
+    must be imported too */
+ #ifndef DL_IMPORT_TYPE
+ #define DL_IMPORT_TYPE
+ #endif
+ 
  #ifdef SYMANTEC__CFM68K__
  #define UsingSharedLibs
  #endif
diff -BcrN --minimal python/dist/src/Include/object.h python.patched/dist/src/Include/object.h
*** python/dist/src/Include/object.h	Mon Apr 24 17:40:45 2000
--- python.patched/dist/src/Include/object.h	Wed Jun 14 12:45:18 2000
***************
*** 109,120 ****
   
  typedef struct _object {
  	PyObject_HEAD
! } PyObject;
  
  typedef struct {
  	PyObject_VAR_HEAD
- } PyVarObject;
  
  
  /*
  Type objects contain a string containing the type name (to help somewhat
--- 109,120 ----
   
  typedef struct _object {
  	PyObject_HEAD
! } DL_IMPORT_TYPE PyObject;
  
  typedef struct {
  	PyObject_VAR_HEAD
  
+ } DL_IMPORT_TYPE PyVarObject;
  
  /*
  Type objects contain a string containing the type name (to help somewhat
***************
*** 170,176 ****
  	unaryfunc nb_float;
  	unaryfunc nb_oct;
  	unaryfunc nb_hex;
! } PyNumberMethods;
  
  typedef struct {
  	inquiry sq_length;
--- 170,176 ----
  	unaryfunc nb_float;
  	unaryfunc nb_oct;
  	unaryfunc nb_hex;
! } DL_IMPORT_TYPE PyNumberMethods;
  
  typedef struct {
  	inquiry sq_length;
***************
*** 181,200 ****
  	intobjargproc sq_ass_item;
  	intintobjargproc sq_ass_slice;
  	objobjproc sq_contains;
! } PySequenceMethods;
  
  typedef struct {
  	inquiry mp_length;
  	binaryfunc mp_subscript;
  	objobjargproc mp_ass_subscript;
! } PyMappingMethods;
  
  typedef struct {
  	getreadbufferproc bf_getreadbuffer;
  	getwritebufferproc bf_getwritebuffer;
  	getsegcountproc bf_getsegcount;
  	getcharbufferproc bf_getcharbuffer;
! } PyBufferProcs;
  	
  
  typedef void (*destructor) Py_PROTO((PyObject *));
--- 181,200 ----
  	intobjargproc sq_ass_item;
  	intintobjargproc sq_ass_slice;
  	objobjproc sq_contains;
! } DL_IMPORT_TYPE PySequenceMethods;
  
  typedef struct {
  	inquiry mp_length;
  	binaryfunc mp_subscript;
  	objobjargproc mp_ass_subscript;
! } DL_IMPORT_TYPE PyMappingMethods;
  
  typedef struct {
  	getreadbufferproc bf_getreadbuffer;
  	getwritebufferproc bf_getwritebuffer;
  	getsegcountproc bf_getsegcount;
  	getcharbufferproc bf_getcharbuffer;
! } DL_IMPORT_TYPE PyBufferProcs;
  	
  
  typedef void (*destructor) Py_PROTO((PyObject *));
***************
*** 256,262 ****
  	int tp_maxalloc;
  	struct _typeobject *tp_next;
  #endif
! } PyTypeObject;
  
  extern DL_IMPORT(PyTypeObject) PyType_Type; /* The type of type objects */
  
--- 256,262 ----
  	int tp_maxalloc;
  	struct _typeobject *tp_next;
  #endif
! } DL_IMPORT_TYPE PyTypeObject;
  
  extern DL_IMPORT(PyTypeObject) PyType_Type; /* The type of type objects */
  
diff -BcrN --minimal python/dist/src/PC/config.h python.patched/dist/src/PC/config.h
*** python/dist/src/PC/config.h	Wed May 10 15:25:32 2000
--- python.patched/dist/src/PC/config.h	Wed Jun 14 12:45:18 2000
***************
*** 42,47 ****
--- 42,78 ----
  #define PREFIX ""
  #define EXEC_PREFIX ""
  
+ /* egcs/gnu-win32 defines __GNUC__ and _WIN32 */
+ 
+ #if defined(__GNUC__) && defined(_WIN32)
+ #define NT	/* NT is obsolete - please use MS_WIN32 instead */
+ #define MS_WIN32
+ #define MS_WINDOWS
+ #define HAVE_CLOCK
+ #define HAVE_STRFTIME
+ #define HAVE_STRERROR
+ #define NT_THREADS
+ #define WITH_THREAD
+ #define WORD_BIT 32
+ #define HAVE_LONG_LONG 1
+ #define LONG_LONG long long
+ #define PYTHONPATH ".\\DLLs;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk"
+ 
+ #ifndef MS_NO_COREDLL
+ #define MS_COREDLL	/* Python core is in a DLL */
+ #ifndef USE_DL_EXPORT
+ #define USE_DL_IMPORT
+ #endif /* !USE_DL_EXPORT */
+ #endif /* !MS_NO_COREDLL */
+ 
+ #ifdef USE_DL_IMPORT
+ #define DL_IMPORT(sym) __declspec(dllimport) sym
+ /* Definition of every type, variables of which may be imported from DLL,
+    must be imported too */
+ #define DL_IMPORT_TYPE __declspec(dllimport)
+ #endif /* USE_DL_IMPORT */
+ #endif /* (defined(__GNUC__) && defined(_WIN32)) */
+ 
  /* Microsoft C defines _MSC_VER */
  #ifdef _MSC_VER
  

--------------149A4E4C425D8C885F0B8B92--