]> Creatis software - gdcm.git/commitdiff
Trial to get gdcmPython working. demo/PrintHeader should now work.
authorfrog <frog>
Wed, 3 Nov 2004 11:54:42 +0000 (11:54 +0000)
committerfrog <frog>
Wed, 3 Nov 2004 11:54:42 +0000 (11:54 +0000)
gdcmPython/README [new file with mode: 0644]
gdcmPython/demo/PrintHeader.py
gdcmPython/gdcm.i

diff --git a/gdcmPython/README b/gdcmPython/README
new file mode 100644 (file)
index 0000000..8cecd8e
--- /dev/null
@@ -0,0 +1,10 @@
+Variables that should be set in order to work with gdcmPython:
+GDCM_DICT_PATH path to the dictionary GDCM_SOURCE/Dicts/
+GDCM_DATA_PATH path to gdcmData
+PYTHONPATH path to both GDCM_BIN and GDCM_BIN/bin
+
+e.g.
+
+export GDCM_DICT_PATH=~/cvs/gdcm/Dicts/
+export GDCM_DATA_PATH=~/cvs/gdcmData/
+export PYTHONPATH=~/cvs/gdcmbin/bin:~/cvs/gdcmbin/
index 65698538eff1ad68df5c3e75f740ddfafb411e2b..3239266fa9e658ff7dc4907f1a529716273e8e20 100644 (file)
@@ -21,7 +21,8 @@ except IndexError:
 #s = raw_input("Hit any key in this window to exit")
 
 ### Build the header element list
-toRead = gdcmHeader(FileName)
+print FileName, type(FileName)
+toRead = gdcm.Header(FileName)
 if not toRead.IsReadable():
    print "The ", FileName, " file is not readable with gdcm. Sorry."
    sys.exit()
index 9ebe8b90510bcfcc3f04146d5fd025314ff6c1ee..f56077fb64b2c713ff143242550bbfb1437fd134 100644 (file)
@@ -74,6 +74,7 @@ typedef  unsigned short guint16;
 typedef  unsigned int guint32;
 
 ////////////////////////////////////////////////////////////////////////////
+// Convert an STL list<> to a python native list
 %typemap(out) std::list<std::string> * {
    PyObject* NewItem = (PyObject*)0;
    PyObject* NewList = PyList_New(0); // The result of this typemap
@@ -89,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<std::string, std::list<std::string> > * {
    PyObject* NewDict = PyDict_New(); // The result of this typemap
    PyObject* NewKey = (PyObject*)0;
@@ -216,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"
@@ -255,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 <string>
+//     #include <iostream>
+//     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<address>. 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....
+/////////////////////////////////////