Version 1.3.28 (unreleased). =========================== 11/21/2005: mmatus [ruby + python] Fixes for directors + pointers, ugly problem with not easy solution. Before we identified this case as problematic: virtual const MyClass& my_method(); but it turns out that all the cases where a pointer, array or reference is returned, are problematic, even for primitive types (as int, double, char*, etc). To try to fix the issue, a new typemap was added, 'directorfree', which is used to 'free' the resources allocated during the 'directorout' phase. At the same time, a primitive garbage collector engine was added to deal with orphans addresses, when needed. The situation now is much better, but still you can have memory exaustation if recursion is used. So, still you need to avoid returning pointers, arrays or references when using director methods. - Added stdint.i 11/14/2005: wsfulton More types added to windows.i, eg UINT8, WORD, BYTE etc. Including windows.i will also enable SWIG to parse the __declspec Microsoft extension, eg __declspec(dllimport). Also other Windows calling conventions such as __stdcall. 11/10/2005: wsfulton New library file for Windows - windows.i. This file will contain useful type information for users who include windows.h. Initial support is for the non ISO integral types: __int8, __int16, __int32, __int64 and unsigned versions. The unsigned versions previously could not be parsed by SWIG. SF #872013. 11/09/2005: wsfulton [Java, C#] Portability warning for files which will overwrite each other on case insensitive file systems such as FAT32/NTFS. This will occur, for example, when two class names are the same barring case. The warning is issued on all platforms and can be suppressed with the usual warning suppression techniques. SF bug #1084507. 11/09/2005: wsfulton ./configure --with-python --with-ruby --with-perl5 etc enable these languages, ie the --with-xxxx options, where no path is specified, work the same as if the option was not specified at all. Based on patches #1335042 #1329048 #1329047. 11/09/2005: dancy [Allegrocl] Add C++ support to the Allegrocl module. Further enhances the C support as well. Some of the features: - MUCH better generation of foreign types based on the C/C++ types for use in defining the FFI on the lisp side. We don't pass everything as a (* :void) any longer. - Uses typemaps for better control of type conversions and code generation in the generated lisp and c++ wrapper code. - CLOS wrapping of pointers returned from foreign space makes it easier to differentiate pointers in user code. The wrapping objects can be passed directly to FF calls. - Defun wrapping of FF calls, allowing for more lispy interface. Conversion, GCing, of lisp objects to foreign objects can be done in the wrapping defun via the use of typemaps. - overload dispatching implemented on the lisp side using generic functions. - Templates and synonymous types supported. 11/07/2005: mmatus [Python] Adding proper support for multi-inheritance in the python side, ie, if you have two C++ wrapped class, Foo and Bar, now: class MyPythonClass(Foo,Bar): .... will properly work, even with directors, and the deallocation of Foo.this and Bar.this will follow correctly. Before, since a class can only have one 'this' instance (not as in C++), only the last base class was properly deletted, or detected with directors. Now 'self.this' can be a list, which will contain the C++ instance pointers for all the base classes. Also, swig.this is responsible for deallocating the C++ instance(s), and the __del__ method is not emitted unless the user preppend/append some code to it. - Swig now can detect memory leaks, ie, if you still use the non-shadow module, and type something like import _example f = _example.new_Foo() and forgot to call _example.delete_Foo(f), then swig will tell you that there is a memory leak. Otherwise, if you always use the shadow module, probably you will never ever see this warning unless there is something wrong inside the swig wrapping code. *** POTENTIAL INCOMPATIBILITY *** If you overloaded the __del__ method, and call the base one without a try block, as in class MyClass(SwigClass): def __del__(self): SwigClass.__del__(self) python could complain that the method SwigClass.__del__ is undefined. Try to use instead: def __del__(self): try: SwigClass.__del__(self) except: pass or simply def __del__(self): 11/02/2005: mmatus [Python] Adding more fun to STL/STD containers, now you can do %template(pyset) std::set; %template(pyvector) std::vector; %template() std::pair; %template(pyvector) std::map; .... The same applies to std::list, std::deque, std::multiset, etc. Then, at the python side you can do now: # C++ std::vector as native python sequence v = pyvector([1,"hello",(1,2)]) print v[1] >> 'hello' print v[2] >> (1,2) # C++ std::set as native python sequence s = pyset() s.insert((1,2)) s.insert(1) s.insert("hello") sum=() for i in s: sum +=(i,) print sum >>> (1, 'hello', (1, 2)) # C++ std::map as native python sequence m = pymap() m["foo"] = "hello" m[1] = (1,2) pm = {} for k in m: pm[k] = m[k] print pm >>> {1: (1, 2), 'foo': 'hello'} ie, the STD/STL containers work as real native python container, with arbitrary item types and so. But since normal C++ containers do not properly ref/unref their items, you should use the safer versions: %template(pyset) std::set; %template(pyvector) std::vector; %template() std::pair; %template(pyvector) std::map; .... where swig::PyObject_ptr is a PyObject * envelope class provided to safely incref/decref the python object. So, now you can use all the STL/STD containers as native Python containers. Note 1: std::map, std::set and the other 'ordered' containers will properly use PyObject_Compare for sorting, when needed. Note 2: all the STL/STD containers have a limit size of SIZE_MAX, ie, you can have manage containers larger than INT_MAX, the python limit. 11/02/2005: mmatus [Python] - add 'iterator()' method for all sequences and additionally 'key_iterator()' for maps. 'iterator()' will always return the native C++ iterator. Additionally, in maps, 'key_iterator()' will return a python iterator using only the map keys. In general the sequence method __iter__ will call 'iterator()', returning the native C++ iterator, but in maps it will call 'key_iterator()', maintaining backward compatibility. Hence, for std::maps, you can play then with the native C++ iterator, which value is a (key, value) pair, by calling map.iterator(), as with map.begin(), map.end(), etc. The difference is that map.iterator() returns a safe 'close' iterator, while map.begin() and map.end() are 'open' iterators. A 'close' iterator knows the begin and the end of the sequence, and it never can seg. fault. A 'open' iterator, as in C++, can seg. fault at the C++ side. # a close iterator is safe in the following example. # the next() method will throw a StopIteration # exception as needed i = seq.iterator() try: while True: sum += i.next() except: pass # an open iterator always need to be checked, # or it will crash at the C++ side current = seq.begin() end = seq.end() while (current != end): sum += current.next() [Python] - Finally, when we call f = Foo() the construction is 'one-way'. Before construction was done something like Foo() (python) -> _new_Foo() (C++) new_Foo() (C++) -> FooPtr() (python) FooPtr() (python) -> Foo() (python) and returning a pointer was done like NewPointerObj() (C++) -> FooPtr() (python) FooPtr(python) -> Foo() (python) ie, we when going back and forward between the C++ and python side. Now since there is no FooPtr the construction process is Foo() (python) -> _new_Foo() (C++) _new_Foo() (C++) -> NewPointerObj() (C++) (no shadow class) and returning a pointer is done NewPointerObj() (C++) (with shadow class) -> NewInstaceObj() (C++) where NewInstanceObj creates a new instance without calling __init__ and it doesn't go 'back' to python, is 'pure' C API. - With this change, and the other ones in the PySwigObject type, which now carries the thisown and swig_type_info pointer, the generated code should be as fast as boost::Python and/or the other python wrappers based in pure Python/C API calls. As a reference, the profiletest_runme.py example, which does a simple call function many times, such as this code: import profiletest a = profiletest.A() b = profiletest.B() for i in range(0,1000000) a = b.fn(a) where fn is defined as 'A* B::fn(A *a) {return a;}', produces the following times nomodern modern swig-1.3.26 19.70s 5.98s swig-CVS 0.99s 0.98s Clearly, there is a large improvement for the python 'nomodern' mode. Still, the 'modern' mode is around 6 times faster than before. For the same test, but using the non-shadow version of the module, we get _profiletest (non-shadow) swig-1.3.26 0.80s swig-CVS 0.60s Hence, now for practical porpuses, the proxy overhead is insignificant. Note that the performance numbers we are showing is for a simple module (two types) and a simple function (one argument). For real situations, with modules with many more types and/or functions with many more parameters, you will see even better results. 10/31/2005: mmatus [Python] - Finally, no more ClassPtr shadow classes. You will see only a clean Class shadow class in the .py file. - No more thisown attribute either, the PySwigObject now carries the ownership info. You can also do something like print self.this.own() >>> True self.this.disown() print self.this.own() >>> False self.this.acquire() print self.this.own() >>> True - Support for iterators in STL/STD containers, for example, if you have %template std::set; you can use the C++ iterators as: s = set_string() s.append("c") s.append("a") s.append("b") b = s.begin() e = s.end() sum = "" while (b != e): sum += b.next() print sum >>> "abc" advance the iterator as in C++ current = s.begin() current += 1 print current.value() >>> "b" now using the reverse operators b = s.rbegin() e = s.rend() sum = "" while (b != e): sum += b.next() print sum >>> "cba" or the 'previous' method b = s.begin() e = s.end() sum = "" while (b != e): sum += e.previous() print sum >>> "cba" or just as in a python fashion for i in s: sum += i Note 1: Iterators in C++ are very powerful, but dangerous too. And in python you can shoot your foot as well as in C++, so, be careful. Note 2: the iterators are 'light', ie, they do not convert sequence elements until you request so, via next(), value() or previous(). If you just increment/decrement one no conversion is performed, for example: b = s.begin() b += 1 b.incr() b.incr(2) b.decr(2) b.decr() b -= 1 only the iterator is modified, and not value wrapper is generated. Other typical C++ operations are also available, such as: print s.end() - s.begin() >>> 3 f = s.begin() + 1 print f.value() >>> "b" l = s.end() - 1 print l.value() >>> "c" etc. Of course, the 'find', 'insert', 'erase', and so on methods also supports iterators now, ie: i = s.begin() i += 1 s.erase(i) for i in s: sum += i print sum >>> "ac" *** POTENTIAL INCOMPATIBILITY *** There is no more 'thisown' attribute. If you use it, you need to change as follows: if (self.thisown): ==> if (self.this.own()): self.thisown = 1 ==> self.this.acquire() self.thisown = 0 ==> self.this.disown() if you really really like the old 'thisown' attribute, you can submit a patch to treat it as a property, and dispatch the new method calls. Of course, before you try, it needs to work with old and new python versions, and with classic and modern python classes. 10/30/2005: mkoeppe [Guile] Make declared and defined linkage of SWIG_init consistent. Reported by Steven G. Johnson (SF patch 1315498). 10/26/2005: mmatus - Added the attribute.i file to the global library director. Now it can be used from other languages that do not use the unified typemap library as well. So, if you have something like: %include attribute.i %attribute(A, int, a, get_a, set_a); struct A { int get_a() const; void set_a(int aa); }; %attribute_ref(B, int, c); struct B { int& c(); }; then in the target language the 'A.a' and 'B.c' attributes will be visible, ie, you can access them as plain variables: f = A() f.a = 3 g = B() g.c = 3 h = f.a + g.c and the proper get/set methods will be dispatched. See attribute.i for more info. - More cleanups around and adding more test-cases. The DISOWN typemap now is tested and working in all the languages that use the unified typemap library, ie, tcl, ruby, perl and python. 10/25/2005: mmatus - Perl, complete the DISOWN typemap. - added the attribute.i file to the unified typemap library (before was only usable from python). - uniform the names for the setter and getter methods in perl,tcl,ruby and python, so, the attribute.i library can work across them. - see the li_attribute.i test-case or the library file Lib/typemaps/attribute.swg for more info about how to use it. 10/24/2005: mmatus - Perl uses now the unified typemap library. - Changes in ruby to use the $track option in typemaps. - Changes in the unified typemap library to follow the convention that all macros that are not used in the C/C++ side starts with %, such as %delete %new_array etc. - Documenting fragments, see fragments.swg. - Cleaner way to use the unified typemap library, include just . Check some of the supported languages: perl, tcl, ruby, python. Always start with the head file, such as python/python.swg tcl/tcl8.swg ruby/ruby.swg perl5/perl5.swg and the principal file that invokes the unified library, such as python/pytypemaps.swg tcl/tcltypemaps.swg ruby/rubytypemaps.swg perl/perltypemaps.swg The file that provide the specialization for each language are the one that provides the basic types: python/pyprimtypes.swg ruby/rubyprimtypes.swg tcl/tclprimtypes.swg perl5/perlprimtypes.swg and the string manipulation: python/pystrings.swg ruby/rubystrings.swg tcl/tclstrings.swg perl5/perlstrings.swg The rest of the files, such as carray.i, are mostly one line files that include the proper typemap library version. 10/23/2005: wuzzeb Chicken: + pointers to member functions finally work properly + add test of member function pointers to cpp_basic.i 10/20/2005: dancy [allegrocl] Added C++ support. Large update, many changes. See newly added Allegro Common Lisp section in lisp.html 10/20/2005: mmatus Ruby, Tcl, Python: - Uniform way to fail (label fail:), now finally SWIG_exception works across the three languages and all the typemaps. - Add proper cleanup code to ruby - More valgrind fixes - Simplify the inline use, it seems a small interface of 20,000 lines (plus many many templates0 can break gcc -O3 easily. - Finalize the typemaps library. All the old *.i files (carray.i, cpointer.i, exception.i) had been implemented in the new typemaps library. 10/19/2005: wuzzeb Update the Runtime Typemap documentation in Typemaps.html 10/18/2005: wuzzeb Chicken: - Correctly handle %ignored classes - Correctly convert long, long long, unsigned long, etc to chicken primitives. (Thanks to Felix Winkelmann) - Using argout parameters when the return value was a wrapped pointer caused a memory corruption. The chicken garbage collector moved a pointer out from under us. This is now fixed by running all the proxy creation functions as continuations after the wrapper function returns. As part of this, we no longer need the chickenfastproxy flag on output typemaps. - using -proxy and -nocollection together works now Before, it was not exporting the destructor in the proxy wrapper. 10/18/2005: mmatus Unifying the typemaps for python, ruby, tcl and in the process, fix several problems in three languages to work in the "canonical" way now stablished in the typemap library SWIG/Lib/typempas The current status of the unification is that everything compiles and runs inside the test-suite and examples directories. And for the first type we have three languages than pass the primitive_types.i case. Also, we have uniform way to treat the errors, for example if you do something like >>> from primitive_types import * >>> print val_uchar(10) 10 >>> print val_uchar(1000) Traceback (most recent call last): File "", line 1, in ? OverflowError: in argument 1 of type 'unsigned char' you get the same exception in all the three languages. And well, many more good things will come from this unification, as proper support of the STL/STD classes for all the languages, and hopefully, we can keep adding other languages. The hardest part, writting a common typemap library that suites the three different languages, is done, and adding another language it is easy now. Still the global unification is not complete, the STL/STD part is next, and probably adding one or two more languages. If you are curious, look at the python, ruby and/or tcl directories to see what is needed to support the new common typemaps library. Still, the final way to integrate a new language could change as we move to integrate the STD/STL. *** POTENTIAL INCOMPATIBILITY *** Some missing typemaps could start working, and change the old expected behavior, specially in ruby and tcl.