interrogate2swig.py

Some documentation on how the kit above works, just in case it is useful.

In makepanda.py:

  • interrogate doesnt actually do very much any more

  • interrogate writes the name of the header files to a global list,

  • and it writes out all the information to an xml file swiginfo.xml

  • interrogatemodule calls generateswigfile

  • generateswigfile is a new function that preprocesses all the headerfiles, specified in the global list, naming the processed files xxx.pre

  • then it calls interrogate2swig.py, passing in the name of the module (ie panda, pandaexpress, framework etc)

  • interrogate2swig.py is going to generate a swig interface file in built/swig, called something like panda.i or pandaexpress.i

  • makepanda.py will execute swig on this interface file, to generate the wrapper .cxx file (libpanda_module.cxx, libpandaexpress_module.cxx, etc) and the python interface file (panda.py, framework.py etc)

  • then it will compile it

  • the wrapper will be linked with the appropriate dll (eg libpanda.dll) to create a new dll with an _ prefix, for example _framework.dll or panda.dll. The name is important, otherwise the python file wont link with it correctly at runtime.

  • the rest of makepanda.py is largely unchanged

interrogate2swig.py:

  • reads the module name and swiginfo.xml filepath from the commandline
  • reads the list of all headerfiles from teh swiginfo file, for that module
  • filters this list against an exclusions list, basically files that are hard to deal with at this time, and generally files that arent necessary in the Python interface (but not always)
  • if the headerfilename doesnt end in _src.h, adds it to a list of #include files athat the C/C++ wrapper file will include, so that it has access to the actual underlying headerfiles.
  • the _src.h files are excluded, because there are special rules for including these files; basically only the corresponding file without a _src postfix should be included, so this is what we do
  • then the preprocessed headerfile is read in, ie the .pre file that makepanda.py generated earlier
  • all class members not in __published: are stripped
  • __declspec(import) and/or __declspec(export) are stripped
  • nested classes are stripped
  • a few enum uses are prefixed with the classname, eg ShadeModel -> qpGeomEnums::ShadeModel (handleenums function)
  • certain classes have additional members added to them, eg PointLight. These members exist in the original headers, but only in public:, not in published:.
  • there’s a load of stuff to process macros; but these are largely obsolete now that we are running the files through a preprocessor beforehand, in makepanda.py
  • it writes out the processed, filtered class to a file pandaraw.swg
  • next it sorts this file in batch mode, making several passes, to create the final swig interface file built/swig/panda.i
  • it also adds in a few %include and %import commands to the head of this interface file, so that it works correctly
  • for example %include “pandatypemaps.i” is added, to provide support for using strings and char*&[] as arguments

Known outstanding issues:

  • overloaded member functions that use strings wont be correctly selected at runtime, eg TexturePool_load_texture(“myfile.jpg”)
  • I think the argument name needs to be replaced by INPUT.
  • It may be sufficient to detect whether there is a const or not. If there is a const, replace by const string &INPUT; and if not replace by string &OUTPUT.
  • one would also need to add a new typemap function for string &OUTPUT to the pandatypemaps.i file that is at the bottom of the post above
  • it may be that strings are almost never returned via the arguments list, which would simplify this somewhat

Hugh