git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7861 626c5289-ae23-0410-ae9c-e8d60b6d4f22
699 lines
22 KiB
Text
699 lines
22 KiB
Text
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):
|
|
<your code here>
|
|
SwigClass.__del__(self)
|
|
|
|
python could complain that the method SwigClass.__del__ is
|
|
undefined. Try to use instead:
|
|
|
|
def __del__(self):
|
|
<your code here>
|
|
try: SwigClass.__del__(self)
|
|
except: pass
|
|
|
|
or simply
|
|
|
|
def __del__(self):
|
|
<your code here>
|
|
|
|
11/02/2005: mmatus
|
|
|
|
[Python] Adding more fun to STL/STD containers, now you
|
|
can do
|
|
|
|
%template(pyset) std::set<PyObject *>;
|
|
%template(pyvector) std::vector<PyObject *>;
|
|
%template() std::pair<PyObject *,PyObject *>;
|
|
%template(pyvector) std::map<PyObject *,PyObject *>;
|
|
....
|
|
|
|
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<swig::PyObject_ptr>;
|
|
%template(pyvector) std::vector<swig::PyObject_ptr>;
|
|
%template() std::pair<swig::PyObject_ptr, swig::PyObject_ptr>;
|
|
%template(pyvector) std::map<swig::PyObject_ptr,swig::PyObject_ptr>;
|
|
....
|
|
|
|
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<set_string> std::set<std::string>;
|
|
|
|
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 <typemaps/swigtypes.swg>.
|
|
|
|
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 "<stdin>", 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.
|
|
|
|
|