From: Rob M. <ma...@ll...> - 2001-04-18 19:58:55
|
> Konrad Hinsen <hi...@cn...> wrote > > Could you give a quick explanation why? I thought the whole point of >> the "extern" specifier was to flag that this variable was defined >> elsewhere. > >Right, but with most platforms' shared library systems, this means >"in another source file that is part of the same shared library", >not "in another shared library" or "in the main executable". > >> Otherwise, doesn't it imply that the API pointer is >> defined in each file that includes arrayobject.h? >> >> i.e. shouldn't headers declare "extern double x" for everything except >> the file that actually defines x? > >If a dynamically loaded module consists of more than one source file, >then all but one of them (the one which calls import_array()) must >define NO_IMPORT_ARRAY before including arrayobject.h. This is also >the answer to Kevin Rodgers' question. > > >However, it seems to me that the current arrangement in NumPy has >another serious drawback: it should be impossible to link NumPy >statically with the Python interpreter, due to multiply defined >symbols. And I am rather sure that this was possible many versions >ago, since I used NumPy on a Cray T3E, which does not have shared >libraries. > >I checked my own extension modules that export a C API, and they all >declare the API pointer static. This is also what the C API export >section in the "Extending & Embedding" manual recommends. (OK, I admit >that I wrote that section, so that is not a coincidence!) > > >So perhaps the best solution is to make this static. Client modules >that consist of more than one source code file with PyArray... calls >must then call import_array() once in every such file, or equivalently >pass on the PyArray_API pointer explicitly between the files. That >sounds quite acceptable to me. > In my experience porting other libraries to the Mac I find that most Unix boxes are not at all upset by what CodeWarrior calls multiple definitions. The answer in that case was in details that are not specified in the C standard. Section 4.8 of "A Reference Manual" by Harbison and Steele goes into the details of how external names are handled. Most UNIX compilers use the mixed Common Model. In this case you can define a global any number of times and if there is no initializer present they are all merged into one much like a Fortran Common block. My point is that what I consider lazy coding practice (not using externs where needed) is tolerated by many C compilers. I am not competent to comment on the impact of shared libraries on all this. -- *-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*- Rob Managan <mailto://ma...@ll...> LLNL ph: 925-423-0903 P.O. Box 808, L-095 FAX: 925-422-3389 Livermore, CA 94551-0808 |