X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=gdcmPython%2Fgdcm.i;h=f56077fb64b2c713ff143242550bbfb1437fd134;hb=f6204e4795251ff95c653e32e8cdca61d2c19880;hp=b4d93b1aa1342c6afe00249243a104fb2d9e7bae;hpb=e28b183ba68aa3cc84a44a779a31f9d906a1ad2f;p=gdcm.git diff --git a/gdcmPython/gdcm.i b/gdcmPython/gdcm.i index b4d93b1a..f56077fb 100644 --- a/gdcmPython/gdcm.i +++ b/gdcmPython/gdcm.i @@ -68,11 +68,13 @@ void gdcmPythonVoidFuncArgDelete(void *arg) } } +using namespace gdcm; %} typedef unsigned short guint16; typedef unsigned int guint32; //////////////////////////////////////////////////////////////////////////// +// Convert an STL list<> to a python native list %typemap(out) std::list * { PyObject* NewItem = (PyObject*)0; PyObject* NewList = PyList_New(0); // The result of this typemap @@ -88,7 +90,7 @@ typedef unsigned int guint32; } //////////////////////////////////////////////////////////////////////////// -// Convert a c++ hash table in a python native dictionary +// Convert an STL map<> (hash table) to a python native dictionary %typemap(out) std::map > * { PyObject* NewDict = PyDict_New(); // The result of this typemap PyObject* NewKey = (PyObject*)0; @@ -215,17 +217,33 @@ typedef unsigned int guint32; } -//////////////////////////////////////////////////////////////////////////// -// Deals with function returning a C++ string. +//////////////////// STL string versus Python str //////////////////////// +// Convertion returning a C++ string. %typemap(out) string, std::string { $result = PyString_FromString(($1).c_str()); } +// Convertion of incoming Python str to STL string %typemap(python, in) const std::string, std::string { $1 = PyString_AsString($input); } +// Same convertion as above but references (since swig converts C++ +// refererences to pointers) +%typemap(python, in) std::string const & +{ + $1 = new std::string( PyString_AsString( $input ) ); +} + +//////////////////////////////////////////////////////////////////////////// +// Because overloading and %rename don't work together (see below Note 1) +// we need to ignore the default constructor. +// The gdcm::Header class doesn't have any SetFilename method anyhow, and +// this constructor is only used internaly (not from the API) so this is +// not a big loss. +%ignore gdcm::Header::Header(); + //////////////////////////////////////////////////////////////////////////// // Warning: Order matters ! %include "gdcmCommon.h" @@ -254,3 +272,50 @@ typedef unsigned int guint32; %include "gdcmUtil.h" %include "gdcmGlobal.h" %include "gdcmDicomDir.h" + +//////////////////////////////////////////////////////////////////////////// +// Notes on swig and this file gdcm.i: +// +///////////////////////////////////// +// Note 1: swig collision of method overloading and %typemap +// Consider the following junk.i file: +// %module junk +// %{ +// #include +// #include +// void Junk(std::string const & bozo) { std::cout << bozo << std::endl; } +// void Junk() { std::cout << "Renamed Junk()" << std::endl; } +// %} +// +// %typemap(python, in) std::string const & +// { +// $1 = new std::string( PyString_AsString( $input ) ); +// } +// +add a note on the rename that works ! +// void Junk(); +// void Junk(std::string const & bozo); +// +// that we compile on linux with: +// swig -c++ -python junk.i +// g++ -g -I/usr/include/python2.3/ -o junk_wrap.o -c junk_wrap.cxx +// g++ junk_wrap.o -shared -g -o _junk.so -L/usr/lib/python2.3/config \ +// -lpython2.3 +// and invoque with: +// python -c 'from junk import *; Junk("aaa") ' +// then we get the following unexpected (for novice) python TypeError: +// TypeError: No matching function for overloaded 'Junk' +// +// This happens because the swig generated code (at least for python) does +// the following two stage process: +// 1/ first do a dynamic dispatch ON THE NUMBER OF ARGUMENTS of the overloaded +// Junk function (the same happens with method of course). [Note that the +// dispatch is NOT done on the type of the arguments]. +// 2/ second apply the typemap. +// When the first dynamic dispatch is executed, the swig generated code +// has no knowledge of the typemap, and thus expects a pointer to a std::string +// type i.e. an argument to Junk of the form _p_std__int
. But this +// is not what python handles to Junk ! An invocation of the form 'Junk("aaa")' +// will make Python pass a PyString to swig (and this is precisely why we +// wrote the typemap). And this will fail.... +/////////////////////////////////////