merge revisions 11243-11872 from trunk to gsoc2009-matevz
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-matevz@12162 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
commit
ab1cd03979
387 changed files with 12383 additions and 4412 deletions
|
|
@ -37,7 +37,6 @@ $(PACKAGE_NAME).1: ccache.yo
|
|||
-yodl2man -o $(PACKAGE_NAME).1 ccache.yo
|
||||
|
||||
web/ccache-man.html: ccache.yo
|
||||
mkdir -p man
|
||||
yodl2html -o web/ccache-man.html ccache.yo
|
||||
|
||||
install: $(PACKAGE_NAME)$(EXEEXT) $(PACKAGE_NAME).1
|
||||
|
|
@ -53,7 +52,7 @@ uninstall: $(PACKAGE_NAME)$(EXEEXT) $(PACKAGE_NAME).1
|
|||
clean:
|
||||
/bin/rm -f $(OBJS) *~ $(PACKAGE_NAME)$(EXEEXT)
|
||||
|
||||
clean-docs:
|
||||
distclean-docs:
|
||||
rm -f $(PACKAGE_NAME).1 web/ccache-man.html
|
||||
|
||||
check : test
|
||||
|
|
@ -63,9 +62,12 @@ test: test.sh
|
|||
|
||||
check: test
|
||||
|
||||
distclean: clean
|
||||
/bin/rm -f Makefile config.h config.sub config.log build-stamp config.status configure config.h
|
||||
distclean: clean distclean-docs
|
||||
/bin/rm -f Makefile config.h config.sub config.log build-stamp config.status config.h.in ccache_swig_config.h
|
||||
|
||||
maintainer-clean: distclean
|
||||
/bin/rm -f configure
|
||||
|
||||
# FIXME: To fix this, test.sh needs to be able to take ccache from the
|
||||
# installed prefix, not from the source dir.
|
||||
installcheck:
|
||||
|
|
|
|||
258
CHANGES
258
CHANGES
|
|
@ -2,6 +2,264 @@ SWIG (Simplified Wrapper and Interface Generator)
|
|||
|
||||
See CHANGES.current for current version.
|
||||
|
||||
Version 1.3.40 (18 August 2009)
|
||||
===============================
|
||||
|
||||
2009-08-17: olly
|
||||
[Perl] Add "#undef do_exec" to our clean up of Perl global
|
||||
namespace pollution.
|
||||
|
||||
2009-08-17: olly
|
||||
[PHP] Fix to wrap a resource returned by __get() in a PHP object (SF#2549217).
|
||||
|
||||
2009-08-17: wsfulton
|
||||
Fix #2797485 After doing a 'make clean', install fails if yodl2man or yodl2html
|
||||
is not available.
|
||||
|
||||
2009-08-16: wsfulton
|
||||
[Octave] Caught exceptions display the type of the C++ exception instead of the
|
||||
generic "c++-side threw an exception" message.
|
||||
|
||||
2009-08-16: wsfulton
|
||||
[Java] When %catches is used, fix so that any classes specified in the "throws"
|
||||
attribute of the "throws" typemap are generated into the Java method's throws clause.
|
||||
|
||||
2009-08-16: wsfulton
|
||||
[C#] Fix exception handling when %catches is used, reported by Juan Manuel Alvarez.
|
||||
|
||||
2009-08-15: wsfulton
|
||||
Fix %template seg fault on some cases of overloading the templated method.
|
||||
Bug reported by Jan Kupec.
|
||||
|
||||
2009-08-15: wsfulton
|
||||
[Ruby] Add numerous missing wrapped methods for std::vector<bool> specialization
|
||||
as reported by Youssef Jones.
|
||||
|
||||
2009-08-14: wsfulton
|
||||
[Perl] Add SWIG_ConvertPtrAndOwn() method into the runtime for smart pointer
|
||||
memory ownership control. shared_ptr support still to be added. Patch from
|
||||
David Fletcher.
|
||||
|
||||
2009-08-14: olly
|
||||
[PHP] PHP5 now wraps static member variables as documented.
|
||||
|
||||
2009-08-14: olly
|
||||
[PHP] Update the PHP "class" example to work with PHP5 and use
|
||||
modern wrapping features.
|
||||
|
||||
2009-08-13: wsfulton
|
||||
[PHP] std::vector wrappers overhaul. They no longer require the
|
||||
specialize_std_vector() macro. Added wrappers for capacity() and reserve().
|
||||
|
||||
2009-08-13: wsfulton
|
||||
[PHP] Add const reference typemaps. const reference primitive types are
|
||||
now passed by value rather than pointer like the other target languages.
|
||||
Fixes SF#2524029.
|
||||
|
||||
2009-08-08: wsfulton
|
||||
[Python] More user friendly AttributeError is raised when there are
|
||||
no constructors generated for the proxy class in the event that the
|
||||
class is abstract - the error message is now
|
||||
"No constructor defined - class is abstract" whereas if there are no
|
||||
public constructors for any other reason and the class is not abstract,
|
||||
the message remains
|
||||
"No constructor defined".
|
||||
[tcl] Similarly for tcl when using -itcl.
|
||||
|
||||
2009-08-04: olly
|
||||
[PHP] Fix generated code to work with PHP 5.3.
|
||||
|
||||
2009-08-04: vmiklos
|
||||
[PHP] Various mathematical functions (which would conflict
|
||||
with the built-in PHP ones) are now automatically handled by
|
||||
adding a 'c_' prefix.
|
||||
|
||||
2009-08-03: wsfulton
|
||||
[C#] The std::vector<T> implementation is improved and now uses $typemap such
|
||||
that the proxy class for T no longer has to be specified in some macros
|
||||
for correct C# compilation; the following macros are deprecated, where
|
||||
CSTYPE was the C# type for the C++ class CTYPE:
|
||||
|
||||
SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE)
|
||||
usage should be removed altogether
|
||||
|
||||
SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE)
|
||||
should be replaced with:
|
||||
SWIG_STD_VECTOR_ENHANCED(CTYPE)
|
||||
|
||||
Some more details in csharp/std_vector.i
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2009-07-31: olly
|
||||
[Python] Fix indentation so that we give a useful error if the
|
||||
module can't be loaded. Patch from Gaetan Lehmann in SF#2829853.
|
||||
|
||||
2009-07-29: wsfulton
|
||||
Add $typemap(method, typelist) special variable macro. This allows
|
||||
the contents of a typemap to be inserted within another typemap.
|
||||
Fully documented in Typemaps.html.
|
||||
|
||||
2009-07-29: vmiklos
|
||||
[PHP] Static member variables are now prefixed with the
|
||||
class name. This allows static member variables with the
|
||||
same name in different classes.
|
||||
|
||||
2009-07-29: olly
|
||||
[Python] Add missing locks to std::map wrappers. Patch from
|
||||
Paul Hampson in SF#2813836.
|
||||
|
||||
2009-07-29: olly
|
||||
[PHP] Fix memory leak in PHP OUTPUT typemaps. Reported by Hitoshi
|
||||
Amano in SF#2826322.
|
||||
|
||||
2009-07-29: olly
|
||||
[PHP] Fix memory leak in PHP resource destructor for classes
|
||||
without a destructor and non-class types. Patch from Hitoshi Amano
|
||||
in SF#2825303.
|
||||
|
||||
2009-07-28: olly
|
||||
[PHP] Update warnings about clashes between identifiers and PHP
|
||||
keywords and automatic renaming to work with the PHP5 class
|
||||
wrappers. Fixes SF#1613679.
|
||||
|
||||
2009-07-28: vmiklos
|
||||
[PHP] If a member function is not public but it has a base
|
||||
which is public, then now a warning is issued and the member
|
||||
function will be public, as PHP requires this.
|
||||
|
||||
2009-07-21: vmiklos
|
||||
[PHP] Director support added.
|
||||
|
||||
2009-07-15: olly
|
||||
[Perl] Don't specify Perl prototype "()" for a constructor with a
|
||||
different name to the class, as such constructors can still take
|
||||
parameters.
|
||||
|
||||
2009-07-12: xavier98
|
||||
[Octave] Add support for Octave 3.2 API
|
||||
|
||||
2009-07-05: olly
|
||||
[PHP] Update the list of PHP keywords - "cfunction" is no longer a
|
||||
keyword in PHP5 and PHP 5.3 added "goto", "namespace", "__DIR__",
|
||||
and "__NAMESPACE__".
|
||||
|
||||
2009-07-03: olly
|
||||
[Tcl] To complement USE_TCL_STUBS, add support for USE_TK_STUBS
|
||||
and SWIG_TCL_STUBS_VERSION. Document all three in the Tcl chapter
|
||||
of the manual. Based on patch from SF#2810380 by Christian
|
||||
Gollwitzer.
|
||||
|
||||
2009-07-02: vmiklos
|
||||
[PHP] Added factory.i for PHP, see the li_factory testcase
|
||||
for more info on how to use it.
|
||||
|
||||
2009-07-02: wsfulton
|
||||
Fix -Wallkw option as reported by Solomon Gibbs.
|
||||
|
||||
2009-07-02: wsfulton
|
||||
Fix syntax error when a nested struct contains a comment containing a * followed
|
||||
eventually by a /. Regression from 1.3.37, reported by Solomon Gibbs.
|
||||
|
||||
2009-07-01: vmiklos
|
||||
[PHP] Unknown properties are no longer ignored in proxy
|
||||
classes.
|
||||
|
||||
2009-07-01: vmiklos
|
||||
[PHP] Fixed %newobject behaviour, previously any method
|
||||
marked with %newobject was handled as a constructor.
|
||||
|
||||
2009-06-30: olly
|
||||
[Ruby] Undefine close and connect macros defined by Ruby API
|
||||
headers as we don't need them and they can clash with C++ methods
|
||||
being wrapped. Patch from Vit Ondruch in SF#2814430.
|
||||
|
||||
2009-06-26: olly
|
||||
[Ruby] Fix to handle FIXNUM values greater than MAXINT passed for a
|
||||
double parameter.
|
||||
|
||||
2009-06-24: wsfulton
|
||||
Fix wrapping methods with default arguments and the compactdefaultargs feature
|
||||
where a class is passed by value and is assigned a default value. The SwigValueWrapper
|
||||
template workaround for a missing default constructor is no longer used as the code
|
||||
generated does not call the default constructor.
|
||||
|
||||
2009-06-16: wsfulton
|
||||
[Java,C#] Fix enum marshalling when %ignore is used on one of the enum items.
|
||||
Incorrect enum values were being passed to the C++ layer or compilation errors resulted.
|
||||
|
||||
2009-06-02: talby
|
||||
[Perl] Resolved reference.i overload support problem
|
||||
identified by John Potowsky.
|
||||
|
||||
2009-05-26: wsfulton
|
||||
[C#] Improved std::map wrappers based on patch from Yuval Baror. The C# proxy
|
||||
now implements System.Collections.Generic.IDictionary<>.
|
||||
|
||||
These std:map wrappers have a non-backwards compatible overhaul to make them
|
||||
like a .NET IDictionary. Some method names have changed as following:
|
||||
set -> setitem (use this[] property now)
|
||||
get -> getitem (use this[] property now)
|
||||
has_key -> ContainsKey
|
||||
del -> Remove
|
||||
clear -> Clear
|
||||
|
||||
The following macros used for std::map wrappers are deprecated and will no longer work:
|
||||
specialize_std_map_on_key
|
||||
specialize_std_map_on_value
|
||||
specialize_std_map_on_both
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2009-05-20: vmiklos
|
||||
[PHP] Add the 'thisown' member to classes. The usage of it
|
||||
is the same as the Python thisown one: it's 1 by default and
|
||||
you can set it to 0 if you want to prevent freeing it. (For
|
||||
example to prevent a double free.)
|
||||
|
||||
2009-05-14: bhy
|
||||
[Python] Fix the wrong pointer value returned by SwigPyObject_repr().
|
||||
|
||||
2009-05-13: mutandiz (Mikel Bancroft)
|
||||
[allegrocl] Minor tweak when wrapping in -nocwrap mode.
|
||||
|
||||
2009-05-11: wsfulton
|
||||
[C#] Improved std::vector wrappers on the C# proxy side from Yuval Baror. These
|
||||
implement IList<> instead of IEnumerable<> where possible.
|
||||
|
||||
2009-04-29: wsfulton
|
||||
[Java, C#] Add the 'notderived' attribute to the javabase and csbase typemaps.
|
||||
When this attribute is set, the typemap will not apply to classes that are derived
|
||||
from a C++ base class, eg
|
||||
%typemap(csbase, notderived="1") SWIGTYPE "CommonBase"
|
||||
|
||||
2009-04-29: olly
|
||||
[Python] Don't attempt to acquire the GIL in situations where we
|
||||
know that it will already be locked. This avoids some dead-locks
|
||||
with mod_python (due to mod_python bugs which are apparently
|
||||
unlikely to ever be fixed), and results in smaller wrappers which
|
||||
run a little faster (in tests with Xapian on x86-64 Ubuntu 9.04,
|
||||
the stripped wrapper library was 11% smaller and ran 2.7% faster).
|
||||
|
||||
2009-04-21: wsfulton
|
||||
[C#] Fix #2753469 - bool &OUTPUT and bool *OUTPUT typemaps initialisation.
|
||||
|
||||
2009-04-09: wsfulton
|
||||
Fix #2746858 - C macro expression using floating point numbers
|
||||
|
||||
2009-03-30: olly
|
||||
[PHP] The default out typemap for char[ANY] now returns the string up to a
|
||||
zero byte, or the end of the array if there is no zero byte. This
|
||||
is the same as Python does, and seems more generally useful than
|
||||
the previous behaviour of returning the whole contents of the array
|
||||
including any zero bytes. If you want the old behaviour, you can provide
|
||||
your own typemap to do this:
|
||||
|
||||
%typemap(out) char [ANY]
|
||||
%{
|
||||
RETVAL_STRINGL($1, $1_dim0, 1);
|
||||
%}
|
||||
|
||||
Version 1.3.39 (21 March 2009)
|
||||
==============================
|
||||
|
||||
|
|
|
|||
405
CHANGES.current
405
CHANGES.current
|
|
@ -1,64 +1,371 @@
|
|||
Version 1.3.40 (in progress)
|
||||
Version 1.3.41 (in progress)
|
||||
============================
|
||||
|
||||
2009-05-26: wsfulton
|
||||
[C#] Improved std::map wrappers based on patch from Yuval Baror. The C# proxy
|
||||
now implements System.Collections.Generic.IDictionary<>.
|
||||
2010-02-27: wsfulton
|
||||
[Python] Remove -dirvtable from the optimizations included by -O as it this option
|
||||
currently leads to memory leaks as reported by Johan Blake.
|
||||
|
||||
These std:map wrappers have a non-backwards compatible overhaul to make them
|
||||
like a .NET IDictionary. Some method names have changed as following:
|
||||
set -> setitem (use this[] property now)
|
||||
get -> getitem (use this[] property now)
|
||||
has_key -> ContainsKey
|
||||
del -> Remove
|
||||
clear -> Clear
|
||||
2010-02-13: wsfulton
|
||||
[Ruby] A few fixes for compiling under ruby-1.9.x including patch from 'Nibble'.
|
||||
|
||||
The following macros used for std::map wrappers are deprecated and will no longer work:
|
||||
specialize_std_map_on_key
|
||||
specialize_std_map_on_value
|
||||
specialize_std_map_on_both
|
||||
2010-02-13: wsfulton
|
||||
[Ruby] Apply patch from Patrick Bennett to fix RARRAY_LEN and RARRAY_PTR usage for Ruby 1.9.x
|
||||
used in various STL wrappers.
|
||||
|
||||
2010-02-13: wsfulton
|
||||
[C#, Java] Fix incorrect multiply defined symbol name error when an enum item
|
||||
and class name have the same name, as reported by Nathan Krieger. Example:
|
||||
|
||||
class Vector {};
|
||||
namespace Text {
|
||||
enum Preference { Vector };
|
||||
}
|
||||
|
||||
This also fixes other incorrect corner case target language symbol name clashes.
|
||||
|
||||
2010-02-11: wsfulton
|
||||
Add the -debug-lsymbols option for displaying the target language layer symbols.
|
||||
|
||||
2010-02-09: wsfulton
|
||||
Fix -MM and -MMD options on Windows. They were not omitting files in the SWIG library as
|
||||
they should be.
|
||||
|
||||
2010-02-08: wsfulton
|
||||
Fix #1807329 - When Makefile dependencies are being generated using the -M family of options
|
||||
on Windows, the file paths have been corrected to use single backslashes rather than double
|
||||
backslashes as path separators.
|
||||
|
||||
2010-02-06: wsfulton
|
||||
Fix #2918902 - language specific files not being generated in correct directory on
|
||||
Windows when using forward slashes for -o, for example:
|
||||
swig -python -c++ -o subdirectory/theinterface_wrap.cpp subdirectory/theinterface.i
|
||||
|
||||
2010-02-05: wsfulton
|
||||
Fix #2894405 - assertion when using -xmlout.
|
||||
|
||||
2010-01-28: wsfulton
|
||||
Fix typemap matching bug when a templated type has a typemap both specialized and not
|
||||
specialized. For example:
|
||||
|
||||
template<typename T> struct XX { ... };
|
||||
%typemap(in) const XX & "..."
|
||||
%typemap(in) const XX< int > & "..."
|
||||
|
||||
resulted in the 2nd typemap being applied for all T in XX< T >.
|
||||
|
||||
2010-01-22: wsfulton
|
||||
Fix #2933129 - typemaps not being found when the unary scope operator (::) is used to denote
|
||||
global scope, the typemap is now used in situations like this:
|
||||
|
||||
struct X {};
|
||||
%typemap(in) const X & "..."
|
||||
void m(const ::X &);
|
||||
|
||||
and this:
|
||||
|
||||
struct X {};
|
||||
%typemap(in) const ::X & "..."
|
||||
void m(const X &);
|
||||
|
||||
2010-01-20: wsfulton
|
||||
Fix some unary scope operator (::) denoting global scope problems in the types generated
|
||||
into the C++ layer. Previously the unary scope operator was dropped in the generated code
|
||||
if the type had any sort of qualifier, for example when using pointers, references, like
|
||||
::foo*, ::foo&, bar< ::foo* >.
|
||||
|
||||
2010-01-13: olly
|
||||
[PHP] Add datetime to the list of PHP predefined classes (patch
|
||||
from David Fletcher in SF#2931042).
|
||||
|
||||
2010-01-11: wsfulton
|
||||
Slight change to warning, error and diagnostic reporting. The warning number is no
|
||||
longer shown within brackets. This is to help default parsing of warning messages by
|
||||
other tools, vim on Unix in particular.
|
||||
|
||||
Example original display using -Fstandard:
|
||||
example.i:20: Warning(401): Nothing known about base class 'B'. Ignored.
|
||||
New display:
|
||||
example.i:20: Warning 401: Nothing known about base class 'B'. Ignored.
|
||||
|
||||
Also subtle fix to -Fmicrosoft format adding in missing space. Example original display:
|
||||
example.i(20): Warning(401): Nothing known about base class 'Base'. Ignored.
|
||||
New display:
|
||||
example.i(20) : Warning 401: Nothing known about base class 'Base'. Ignored.
|
||||
|
||||
2010-01-10: wsfulton
|
||||
Fix a few inconsistencies in reporting of file/line numberings including modifying
|
||||
the overload warnings 509, 512, 516, 474, 475 to now be two line warnings.
|
||||
|
||||
2010-01-10: wsfulton
|
||||
Modify -debug-tags output to use standard file name/line reporting so that editors
|
||||
can easily navigate to the appropriate lines.
|
||||
Was typically:
|
||||
. top . include . include (/usr/share/swig/temp/trunk/Lib/swig.swg:312)
|
||||
. top . include . include . include (/usr/share/swig/temp/trunk/Lib/swigwarnings.swg:39)
|
||||
now:
|
||||
/usr/share/swig/temp/trunk/Lib/swig.swg:312: . top . include . include
|
||||
/usr/share/swig/temp/trunk/Lib/swigwarnings.swg:39: . top . include . include . include
|
||||
|
||||
2010-01-03: wsfulton
|
||||
Fix missing file/line numbers for typemap warnings and in output from the
|
||||
-debug-tmsearch/-debug-tmused options.
|
||||
|
||||
2010-01-03: wsfulton
|
||||
Add typemaps used debugging option (-debug-tmused). When used each line displays
|
||||
the typemap used for each type for which code is being generated including the file
|
||||
and line number related to the type. This is effectively a condensed form of the
|
||||
-debug-tmsearch option. Documented in Typemaps.html.
|
||||
|
||||
2009-12-23: wsfulton
|
||||
Fix for %javaexception and directors so that all the appropriate throws clauses
|
||||
are generated. Problem reported by Peter Greenwood.
|
||||
|
||||
2009-12-20: wsfulton
|
||||
Add -debug-tmsearch option for debugging the typemap pattern matching rules.
|
||||
Documented in Typemaps.html.
|
||||
|
||||
2009-12-12: wsfulton
|
||||
[Octave] Remove the -api option and use the new OCTAVE_API_VERSION_NUMBER
|
||||
macro provided in the octave headers for determining the api version instead.
|
||||
|
||||
2009-12-04: olly
|
||||
[Ruby] Improve support for Ruby 1.9 under GCC. Addresses part of
|
||||
SF#2859614.
|
||||
|
||||
2009-12-04: olly
|
||||
Fix handling of modulo operator (%) in constant expressions
|
||||
(SF#2818562).
|
||||
|
||||
2009-12-04: olly
|
||||
[PHP] "empty" is a reserved word in PHP, so rename empty() method
|
||||
on STL classes to "is_empty()" (previously this was automatically
|
||||
renamed to "c_empty()").
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2009-12-03: olly
|
||||
[PHP] Add typemaps for long long and unsigned long long, and for
|
||||
pointer to method.
|
||||
|
||||
2009-12-02: olly
|
||||
[PHP] Fix warning and rename of reserved class name to be case
|
||||
insensitive.
|
||||
|
||||
2009-12-01: wsfulton
|
||||
Revert support for %extend and memberin typemaps added in swig-1.3.39. The
|
||||
memberin typemaps are ignored again for member variables within a %extend block.
|
||||
Documentation inconsistency reported by Torsten Landschoff.
|
||||
|
||||
2009-11-29: wsfulton
|
||||
[Java, C#] Fix generated quoting when using %javaconst(1)/%csconst(1) for
|
||||
static const char member variables.
|
||||
|
||||
%javaconst(1) A;
|
||||
%csconst(1) A;
|
||||
struct X {
|
||||
static const char A = 'A';
|
||||
};
|
||||
|
||||
2009-11-26: wsfulton
|
||||
[Java, C#] Fix %javaconst(1)/%csconst(1) for static const member variables to
|
||||
use the actual constant value if it is specified, rather than the C++ code to
|
||||
access the member.
|
||||
|
||||
%javaconst(1) EN;
|
||||
%csconst(1) EN;
|
||||
struct X {
|
||||
static const int EN = 2;
|
||||
};
|
||||
|
||||
2009-11-23: wsfulton
|
||||
C++ nested typedef classes can now be handled too, for example:
|
||||
struct Outer {
|
||||
typedef Foo { } FooTypedef1, FooTypedef2;
|
||||
};
|
||||
|
||||
2009-11-18: wsfulton
|
||||
The wrappers for C nested structs are now generated in the same order as declared
|
||||
in the parsed code.
|
||||
|
||||
2009-11-18: wsfulton
|
||||
Fix #491476 - multiple declarations of nested structs, for example:
|
||||
struct Outer {
|
||||
struct {
|
||||
int val;
|
||||
} inner1, inner2, *inner3, inner4[1];
|
||||
} outer;
|
||||
|
||||
2009-11-17: wsfulton
|
||||
Fix parsing of enum declaration and initialization, for example:
|
||||
|
||||
enum ABC {
|
||||
a,
|
||||
b,
|
||||
c
|
||||
} A = a, *pC = &C, array[3] = {a, b, c};
|
||||
|
||||
2009-11-17: wsfulton
|
||||
Fix parsing of struct declaration and initialization, for example:
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
} instance = { 10 };
|
||||
|
||||
2009-11-15: wsfulton
|
||||
Fix #1960977 - Syntax error parsing derived nested class declaration and member
|
||||
variable instance.
|
||||
|
||||
2009-11-14: wsfulton
|
||||
Fix #2310483 - function pointer typedef within extern "C" block.
|
||||
|
||||
2009-11-13: wsfulton
|
||||
Fix usage of nested template classes within templated classes so that compileable code
|
||||
is generated.
|
||||
|
||||
2009-11-13: olly
|
||||
[php] Fix place where class prefix (as specified with -prefix)
|
||||
wasn't being used. Patch from gverbruggen in SF#2892647.
|
||||
|
||||
2009-11-12: wsfulton
|
||||
Fix usage of nested template classes so that compileable code is generated - the nested
|
||||
template class is now treated like a normal nested classes, that is, as an opaque type
|
||||
unless the nestedworkaround feature is used.
|
||||
|
||||
2009-11-12: wsfulton
|
||||
Replace SWIGWARN_PARSE_NESTED_CLASS with SWIGWARN_PARSE_NAMED_NESTED_CLASS and
|
||||
SWIGWARN_PARSE_UNNAMED_NESTED_CLASS for named and unnamed nested classes respectively.
|
||||
|
||||
Named nested class ignored warnings can now be suppressed by name using %warnfilter, eg:
|
||||
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
|
||||
|
||||
but clearly unnamed nested classes cannot and the global suppression is still required, eg:
|
||||
|
||||
#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS
|
||||
|
||||
2009-11-11: wsfulton
|
||||
Added the nestedworkaround feature as a way to use the full functionality of a nested class
|
||||
(C++ mode only). It removes the nested class from SWIG's type information so it is as if SWIG
|
||||
had never parsed the nested class. The documented nested class workarounds using a global
|
||||
fake class stopped working when SWIG treated the nested class as an opaque pointer, and
|
||||
this feature reverts this behaviour. The documentation has been updated with details of how
|
||||
to use and implement it, see the "Nested classes" section in SWIGPlus.html.
|
||||
|
||||
2009-11-11: wsfulton
|
||||
There were a number of C++ cases where nested classes/structs/unions were being handled
|
||||
as if C code was being parsed which would oftentimes lead to uncompileable code as an
|
||||
attempt was made to wrap the nested structs like it is documented for C code. Now all
|
||||
nested structs/classes/unions are ignored in C++ mode, as was always documented. However,
|
||||
there is an improvement as usage of nested structs/classes/unions is now always treated
|
||||
as an opaque type by default, resulting in generated code that should always compile.
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2009-05-14: bhy
|
||||
[Python] Fix the wrong pointer value returned by SwigPyObject_repr().
|
||||
2009-11-09: drjoe
|
||||
Fix R for -fcompact and add std_map.i
|
||||
|
||||
2009-05-13: mutandiz (Mikel Bancroft)
|
||||
[allegrocl] Minor tweak when wrapping in -nocwrap mode.
|
||||
2009-11-08: wsfulton
|
||||
Fix inconsistency for nested structs/unions/classes. Uncompileable code was being
|
||||
generated when inner struct and union declarations were used as types within the
|
||||
inner struct. The inner struct/union is now treated as a forward declaration making the
|
||||
behaviour the same as an inner class. (C++ code), eg:
|
||||
|
||||
2009-05-11: wsfulton
|
||||
[C#] Improved std::vector wrappers on the C# proxy side from Yuval Baror. These
|
||||
implement IList<> instead of IEnumerable<> where possible.
|
||||
struct Outer {
|
||||
struct InnerStruct { int x; };
|
||||
InnerStruct* getInnerStruct();
|
||||
};
|
||||
|
||||
2009-04-29: wsfulton
|
||||
[Java, C#] Add the 'notderived' attribute to the javabase and csbase typemaps.
|
||||
When this attribute is set, the typemap will not apply to classes that are derived
|
||||
from a C++ base class, eg
|
||||
%typemap(csbase, notderived="1") SWIGTYPE "CommonBase"
|
||||
2009-11-08: wsfulton
|
||||
Ignored nested class/struct warnings now display the name of the ignored class/struct.
|
||||
|
||||
2009-04-29: olly
|
||||
[Python] Don't attempt to acquire the GIL in situations where we
|
||||
know that it will already be locked. This avoids some dead-locks
|
||||
with mod_python (due to mod_python bugs which are apparently
|
||||
unlikely to ever be fixed), and results in smaller wrappers which
|
||||
run a little faster (in tests with Xapian on x86-64 Ubuntu 9.04,
|
||||
the stripped wrapper library was 11% smaller and ran 2.7% faster).
|
||||
2009-11-07: wsfulton
|
||||
Bug #1514681 - Fix nested template classes within a namespace generated uncompileable
|
||||
code and introduced strange side effects to other wrapper code especially code
|
||||
after the nested template class. Note that nested template classes are still ignored.
|
||||
|
||||
2009-04-21: wsfulton
|
||||
[C#] Fix #2753469 - bool &OUTPUT and bool *OUTPUT typemaps initialisation.
|
||||
2009-11-07: wsfulton
|
||||
Add new debug options:
|
||||
-debug-symtabs - Display symbol tables information
|
||||
-debug-symbols - Display target language symbols in the symbol tables
|
||||
-debug-csymbols - Display C symbols in the symbol tables
|
||||
|
||||
2009-04-09: wsfulton
|
||||
Fix #2746858 - C macro expression using floating point numbers
|
||||
2009-11-03: wsfulton
|
||||
Fix some usage of unary scope operator (::) denoting global scope, for example:
|
||||
|
||||
2009-03-30: olly
|
||||
[PHP] The default out typemap for char[ANY] now returns the string up to a
|
||||
zero byte, or the end of the array if there is no zero byte. This
|
||||
is the same as Python does, and seems more generally useful than
|
||||
the previous behaviour of returning the whole contents of the array
|
||||
including any zero bytes. If you want the old behaviour, you can provide
|
||||
your own typemap to do this:
|
||||
namespace AA { /* ... */ }
|
||||
using namespace ::AA;
|
||||
|
||||
and bug #1816802 - SwigValueWrapper should be used:
|
||||
|
||||
struct CC {
|
||||
CC(int); // no default constructor
|
||||
};
|
||||
::CC x();
|
||||
|
||||
and in template parameter specializations:
|
||||
|
||||
struct S {};
|
||||
template <typename T> struct X { void a() {}; };
|
||||
template <> struct X<S> { void b() {}; };
|
||||
%template(MyTConcrete) X< ::S >;
|
||||
|
||||
plus probably some other corner case usage of ::.
|
||||
|
||||
2009-11-02: olly
|
||||
[Python] Fix potential memory leak in initialisation code for the
|
||||
generated module.
|
||||
|
||||
2009-10-23: wsfulton
|
||||
Fix seg fault when using a named nested template instantiation using %template(name)
|
||||
within a class. A warning that these are not supported is now issued plus processing
|
||||
continues as if no name was given.
|
||||
|
||||
2009-10-20: wsfulton
|
||||
[Python] Fix std::vector<const T*>. This would previously compile, but not run correctly.
|
||||
|
||||
2009-10-20: wsfulton
|
||||
Fixed previously fairly poor template partial specialization and explicit
|
||||
specialization support. Numerous bugs in this area have been fixed including:
|
||||
|
||||
- Template argument deduction implemented for template type arguments, eg this now
|
||||
works:
|
||||
template<typename T> class X {};
|
||||
template<typename T> class X<T *> {};
|
||||
%template(X1) X<const int *>; // Chooses T * specialization
|
||||
|
||||
and more complex cases with multiple parameters and a mix of template argument
|
||||
deduction and explicitly specialised parameters, eg:
|
||||
template <typename T1, typename T2> struct TwoParm { void a() {} };
|
||||
template <typename T1> struct TwoParm<T1 *, int *> { void e() {} };
|
||||
%template(E) TwoParm<int **, int *>;
|
||||
|
||||
Note that the primary template must now be in scope, like in C++, when
|
||||
an explicit or partial specialization is instantiated with %template.
|
||||
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2009-09-14: wsfulton
|
||||
[C#] Add %csattributes for adding C# attributes to enum values, see docs for example.
|
||||
|
||||
2009-09-11: wsfulton
|
||||
Fix memmove regression in cdata.i as reported by Adriaan Renting.
|
||||
|
||||
2009-09-07: wsfulton
|
||||
Fix constant expressions containing <= or >=.
|
||||
|
||||
2009-09-02: wsfulton
|
||||
The following operators in constant expressions now result in type bool for C++
|
||||
wrappers and remain as type int for C wrappers, as per each standard:
|
||||
|
||||
&& || == != < > <= >= (Actually the last 4 are still broken). For example:
|
||||
|
||||
#define A 10
|
||||
#define B 10
|
||||
#define A_EQ_B A == B // now wrapped as type bool for C++
|
||||
#define A_AND_B A && B // now wrapped as type bool for C++
|
||||
|
||||
2009-09-02: wsfulton
|
||||
Fix #2845746. true and false are now recognised keywords (only when wrapping C++).
|
||||
Constants such as the following are now wrapped (as type bool):
|
||||
#define FOO true
|
||||
#define BAR FOO && false
|
||||
|
||||
%typemap(out) char [ANY]
|
||||
%{
|
||||
RETVAL_STRINGL($1, $1_dim0, 1);
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -1070,31 +1070,35 @@ With each is the cast that can be used in the debugger to extract the underlying
|
|||
<p>
|
||||
<li>String *s;</li>
|
||||
<br>
|
||||
(String *)((DohBase *)s)->data
|
||||
(struct String *)((DohBase *)s)->data
|
||||
<br>
|
||||
The underlying char * string can be displayed with
|
||||
<br>
|
||||
((String *)((DohBase *)s)->data)->str
|
||||
(*(struct String *)(((DohBase *)s)->data)).str
|
||||
|
||||
<p>
|
||||
<li>SwigType *t;</li>
|
||||
<br>
|
||||
(String *)((DohBase *)t)->data
|
||||
(struct String *)((DohBase *)t)->data
|
||||
<br>
|
||||
The underlying char * string can be displayed with
|
||||
<br>
|
||||
((String *)((DohBase *)t)->data)->str
|
||||
(*(struct String *)(((DohBase *)t)->data)).str
|
||||
|
||||
<p>
|
||||
<li>String_or_char *sc;</li>
|
||||
<li>const_String_or_char_ptr sc;</li>
|
||||
Either <br>
|
||||
((String *)((DohBase *)sc)->data)->str
|
||||
(*(struct String *)(((DohBase *)sc)->data)).str
|
||||
<br> or <br>
|
||||
(char *)sc
|
||||
<br> will work depending on whether the underlying type is really a String * or char *.
|
||||
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Please also read the Debugging Functions section in <a href="tree.html">SWIG Parse Tree Handling</a> for the <tt>Swig_print_node()</tt>, <tt>Swig_print_tree()</tt> and <tt>Swig_print_tags()</tt> functions for displaying node contents. It is often easier to place a few calls to these functions in code of interest and recompile than use the debugger.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
Copyright (C) 1999-2004 SWIG Development Team.
|
||||
|
||||
|
|
|
|||
|
|
@ -218,10 +218,10 @@ The following functions are used to help debug SWIG parse trees.
|
|||
<blockquote>
|
||||
Prints the tag-structure of the parse tree to standard output. <tt>node</tt> is the top-level parse tree node. <tt>prefix</tt> is
|
||||
a string prefix thats added to the start of each line. Normally, you would specify the empty string or NIL for <tt>prefix</tt>.
|
||||
This function is called by the <tt>-dump_tags</tt> option to SWIG.
|
||||
This function is called by the <tt>-debug-tags</tt> option to SWIG.
|
||||
|
||||
<pre>
|
||||
% swig -dump_tags -python example.i
|
||||
% swig -debug-tags -python example.i
|
||||
. top (:1)
|
||||
. top . include (/Users/beazley/Projects/share/swig/1.3.31/swig.swg:0)
|
||||
. top . include . include (/Users/beazley/Projects/share/swig/1.3.31/swigwarnings.swg:0)
|
||||
|
|
@ -243,7 +243,7 @@ Since many language modules include hundreds of typemaps and other information,
|
|||
|
||||
<blockquote>
|
||||
Prints the contents of a parse tree node, including all children, to standard output. The output includes all attributes
|
||||
and other details. The command line option <tt>-dump_tree</tt> produces output generated by this function.
|
||||
and other details.
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
|
|
@ -251,8 +251,8 @@ and other details. The command line option <tt>-dump_tree</tt> produces output
|
|||
|
||||
<blockquote>
|
||||
Prints the same output as <tt>Swig_print_node()</tt> except that it also processes all of the siblings of <tt>node</tt>. This can
|
||||
be used to dump the entire parse tree to standard output. Use the command line option <tt>-dump_tree</tt> to get
|
||||
the output of this function for a SWIG input file.
|
||||
be used to dump the entire parse tree to standard output. The command line options <tt>-debug-module</tt>
|
||||
and <tt>-debug-top</tt> use this function to display the parse tree for a SWIG input file.
|
||||
</blockquote>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<ul>
|
||||
<li><a href="#Allegrocl_nn2">Basics</a>
|
||||
<ul>
|
||||
<li><a href="#Allegrocl_nn3">Running Swig</a>
|
||||
<li><a href="#Allegrocl_nn3">Running SWIG</a>
|
||||
<li><a href="#Allegrocl_nn4">Command Line Options</a>
|
||||
<li><a href="#Allegrocl_nn5">Inserting user code into generated files</a>
|
||||
</ul>
|
||||
|
|
@ -138,7 +138,7 @@ to it.
|
|||
<H2><a name="Allegrocl_nn2"></a>17.1 Basics</H2>
|
||||
|
||||
|
||||
<H3><a name="Allegrocl_nn3"></a>17.1.1 Running Swig</H3>
|
||||
<H3><a name="Allegrocl_nn3"></a>17.1.1 Running SWIG</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
|
||||
|
||||
|
||||
<b>Disclaimer: This chapter is under construction.</b>
|
||||
|
||||
<p>
|
||||
In Chapter 3, SWIG's treatment of basic datatypes and pointers was
|
||||
described. In particular, primitive types such as <tt>int</tt> and
|
||||
|
|
@ -351,7 +349,7 @@ function like this in an interface file :</p>
|
|||
|
||||
<div class="code"><pre>
|
||||
%module example
|
||||
%include typemaps.i
|
||||
%include "typemaps.i"
|
||||
...
|
||||
%{
|
||||
extern void negate(double *);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ The PInvoke interface has been chosen over Microsoft's Managed C++ interface as
|
|||
PInvoke is part of the ECMA/ISO C# specification.
|
||||
It is also better suited for robust production environments due to the Managed C++ flaw called the
|
||||
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vcconMixedDLLLoadingProblem.asp">Mixed DLL Loading Problem</a>.
|
||||
Swig C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using
|
||||
SWIG C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using
|
||||
<a href="http://www.mono-project.com/">Mono</a> and <a href="http://www.dotgnu.org/pnet.html">Portable.NET</a>.
|
||||
</p>
|
||||
|
||||
|
|
@ -99,6 +99,7 @@ namespace com.bloggs.widget {
|
|||
...
|
||||
}
|
||||
</pre></div>
|
||||
Note that by default, the generated C# classes have no namespace and the module name is unrelated to namespaces. The module name is just like in Java and is merely used to name some of the generated classes.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
|
@ -131,7 +132,7 @@ If it was used, it would generate an illegal runtime initialisation via a PInvok
|
|||
C# doesn't support the notion of throws clauses.
|
||||
Therefore there is no 'throws' typemap attribute support for adding exception classes to a throws clause.
|
||||
Likewise there is no need for an equivalent to <tt>%javaexception</tt>.
|
||||
In fact, throwing C# exceptions works quite differently, see <a href="CSharp.html#csharp_exceptions">C# Exceptions></a> below.
|
||||
In fact, throwing C# exceptions works quite differently, see <a href="CSharp.html#csharp_exceptions">C# Exceptions</a> below.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
|
@ -248,7 +249,9 @@ public static extern IntPtr function(string jarg1);
|
|||
<p>
|
||||
Support for type attributes.
|
||||
The 'imtype' and 'cstype' typemaps can have an optional <tt>inattributes</tt> and <tt>outattributes</tt> typemap attribute.
|
||||
There are C# attributes and typemap attributes, don't get confused!!
|
||||
The 'imtype' typemap can also have an optional <tt>directorinattributes</tt> and <tt>directoroutattributes</tt>
|
||||
typemap attribute which attaches to director delegates, an implementation detail of directors, see <a href="#csharp_directors_implementation">directors implementation</a>.
|
||||
Note that there are C# attributes and typemap attributes, don't get confused between the two!!
|
||||
The C# attributes specified in these typemap attributes are generated wherever the type is used in the C# wrappers.
|
||||
These can be used to specify any C# attribute associated with a C/C++ type, but are more typically used for the C# <tt>MarshalAs</tt> attribute.
|
||||
For example:
|
||||
|
|
@ -292,11 +295,16 @@ These attributes are associated with the C/C++ parameter type or return type, wh
|
|||
the attribute features and typemaps covered next.
|
||||
Note that all these different C# attributes can be combined so that a method has more than one attribute.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <tt>directorinattributes</tt> and <tt>directoroutattributes</tt> typemap attribute are attached to the delegates in the director class, for example, the SwigDelegateBase_0
|
||||
</p>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>
|
||||
Support for attaching C# attributes to wrapped methods and variables.
|
||||
Support for attaching C# attributes to wrapped methods, variables and enum values.
|
||||
This is done using the <tt>%csattributes</tt> feature, see <a href="Customization.html#features">%feature directives</a>.
|
||||
Note that C# attributes are attached to proxy classes and enums using the <tt>csattributes</tt> typemap.
|
||||
For example, imagine we have a custom attribute class, <tt>ThreadSafeAttribute</tt>, for labelling thread safety.
|
||||
|
|
@ -343,6 +351,38 @@ they can be added using the 'csvarin' and 'csvarout' typemaps respectively.
|
|||
Note that the type used for the property is specified in the 'cstype' typemap.
|
||||
If the 'out' attribute exists in this typemap, then the type used is from the 'out' attribute.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
An example for attaching attributes to the enum and enum values is shown below.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(csattributes) Couleur "[System.ComponentModel.Description(\"Colours\")]"
|
||||
%csattributes Rouge "[System.ComponentModel.Description(\"Red\")]"
|
||||
%csattributes Vert "[System.ComponentModel.Description(\"Green\")]"
|
||||
%inline %{
|
||||
enum Couleur { Rouge, Orange, Vert };
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
which will result in the following C# enum:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
[System.ComponentModel.Description("Colours")]
|
||||
public enum Couleur {
|
||||
[System.ComponentModel.Description("Red")]
|
||||
Rouge,
|
||||
Orange,
|
||||
[System.ComponentModel.Description("Green")]
|
||||
Vert
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
|
@ -947,7 +987,7 @@ without setting the <tt>canthrow</tt> attribute you will get a warning message s
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
example.i:21: Warning(845): Unmanaged code contains a call to a SWIG_CSharpSetPendingException
|
||||
example.i:21: Warning 845: Unmanaged code contains a call to a SWIG_CSharpSetPendingException
|
||||
method and C# code does not handle pending exceptions via the canthrow attribute.
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -337,25 +337,31 @@
|
|||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn10">Typemap specifications</a>
|
||||
<ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn11">Defining a typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_defining">Defining a typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn12">Typemap scope</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn13">Copying a typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn14">Deleting a typemap</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn15">Placement of typemaps</a>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn16">Pattern matching rules</a>
|
||||
<li><a href="Typemaps.html#Typemaps_pattern_matching">Pattern matching rules</a>
|
||||
<ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn17">Basic matching rules</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn18">Typedef reductions</a>
|
||||
<li><a href="Typemaps.html#Typemaps_typedef_reductions">Typedef reductions</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn19">Default typemaps</a>
|
||||
<li><a href="Typemaps.html#Typemaps_mixed_default">Mixed default typemaps</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn20">Multi-arguments typemaps</a>
|
||||
<li><a href="Typemaps.html#Typemaps_debugging_search">Debugging typemap pattern matching</a>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn21">Code generation rules</a>
|
||||
<ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn22">Scope</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn23">Declaring new local variables</a>
|
||||
<li><a href="Typemaps.html#Typemaps_special_variables">Special variables</a>
|
||||
<li><a href="Typemaps.html#Typemaps_special_variable_macros">Special variable macros</a>
|
||||
<ul>
|
||||
<li><a href="Typemaps.html#Typemaps_special_macro_descriptor">$descriptor(type)</a>
|
||||
<li><a href="Typemaps.html#Typemaps_special_macro_typemap">$typemap(method, typepattern)</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn25">Common typemap methods</a>
|
||||
<ul>
|
||||
|
|
@ -378,13 +384,13 @@
|
|||
<li><a href="Typemaps.html#Typemaps_nn40">Typemaps for arrays</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn41">Implementing constraints with typemaps</a>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn43">Typemaps for multiple languages</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn43">Typemaps for multiple target languages</a>
|
||||
<li><a href="Typemaps.html#Typemaps_optimal">Optimal code generation when returning by value</a>
|
||||
<li><a href="Typemaps.html#Typemaps_multi_argument_typemaps">Multi-argument typemaps</a>
|
||||
<li><a href="Typemaps.html#runtime_type_checker">The run-time type checker</a>
|
||||
<ul>
|
||||
<li><a href="Typemaps.html#Typemaps_nn45">Implementation</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn46">Usage</a>
|
||||
<li><a href="Typemaps.html#Typemaps_runtime_type_checker_usage">Usage</a>
|
||||
</ul>
|
||||
<li><a href="Typemaps.html#Typemaps_overloading">Typemaps and overloading</a>
|
||||
<li><a href="Typemaps.html#Typemaps_nn48">More about <tt>%apply</tt> and <tt>%clear</tt></a>
|
||||
|
|
@ -488,6 +494,7 @@
|
|||
<!-- INDEX -->
|
||||
<div class="sectiontoc">
|
||||
<ul>
|
||||
<li><a href="Modules.html#Modules_introduction">Modules Introduction</a>
|
||||
<li><a href="Modules.html#Modules_nn1">Basics</a>
|
||||
<li><a href="Modules.html#Modules_nn2">The SWIG runtime code</a>
|
||||
<li><a href="Modules.html#external_run_time">External access to the runtime</a>
|
||||
|
|
@ -531,7 +538,7 @@
|
|||
<ul>
|
||||
<li><a href="Allegrocl.html#Allegrocl_nn2">Basics</a>
|
||||
<ul>
|
||||
<li><a href="Allegrocl.html#Allegrocl_nn3">Running Swig</a>
|
||||
<li><a href="Allegrocl.html#Allegrocl_nn3">Running SWIG</a>
|
||||
<li><a href="Allegrocl.html#Allegrocl_nn4">Command Line Options</a>
|
||||
<li><a href="Allegrocl.html#Allegrocl_nn5">Inserting user code into generated files</a>
|
||||
</ul>
|
||||
|
|
@ -1114,7 +1121,7 @@
|
|||
<li><a href="Perl5.html#Perl5_nn24">Modules and packages</a>
|
||||
</ul>
|
||||
<li><a href="Perl5.html#Perl5_nn25">Input and output parameters</a>
|
||||
<li><a href="Perl5.html#Perl5_nn26">Exception handling </a>
|
||||
<li><a href="Perl5.html#Perl5_nn26">Exception handling</a>
|
||||
<li><a href="Perl5.html#Perl5_nn27">Remapping datatypes with typemaps</a>
|
||||
<ul>
|
||||
<li><a href="Perl5.html#Perl5_nn28">A simple typemap example</a>
|
||||
|
|
@ -1124,8 +1131,8 @@
|
|||
</ul>
|
||||
<li><a href="Perl5.html#Perl5_nn32">Typemap Examples</a>
|
||||
<ul>
|
||||
<li><a href="Perl5.html#Perl5_nn33">Converting a Perl5 array to a char ** </a>
|
||||
<li><a href="Perl5.html#Perl5_nn34">Return values </a>
|
||||
<li><a href="Perl5.html#Perl5_nn33">Converting a Perl5 array to a char **</a>
|
||||
<li><a href="Perl5.html#Perl5_nn34">Return values</a>
|
||||
<li><a href="Perl5.html#Perl5_nn35">Returning values from arguments</a>
|
||||
<li><a href="Perl5.html#Perl5_nn36">Accessing array structure members</a>
|
||||
<li><a href="Perl5.html#Perl5_nn37">Turning Perl references into C pointers</a>
|
||||
|
|
@ -1172,6 +1179,16 @@
|
|||
</ul>
|
||||
<li><a href="Php.html#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</a>
|
||||
</ul>
|
||||
<li><a href="Php.html#Php_nn3">Cross language polymorphism</a>
|
||||
<ul>
|
||||
<li><a href="Php.html#Php_nn3_1">Enabling directors</a>
|
||||
<li><a href="Php.html#Php_nn3_2">Director classes</a>
|
||||
<li><a href="Php.html#Php_nn3_3">Ownership and object destruction</a>
|
||||
<li><a href="Php.html#Php_nn3_4">Exception unrolling</a>
|
||||
<li><a href="Php.html#Php_nn3_5">Overhead and code bloat</a>
|
||||
<li><a href="Php.html#Php_nn3_6">Typemaps</a>
|
||||
<li><a href="Php.html#Php_nn3_7">Miscellaneous</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
|
@ -1264,9 +1281,6 @@
|
|||
<li><a href="Python.html#Python_nn47">Simple pointers</a>
|
||||
<li><a href="Python.html#Python_nn48">Unbounded C Arrays</a>
|
||||
<li><a href="Python.html#Python_nn49">String handling</a>
|
||||
<li><a href="Python.html#Python_nn50">Arrays</a>
|
||||
<li><a href="Python.html#Python_nn51">String arrays</a>
|
||||
<li><a href="Python.html#Python_nn52">STL wrappers</a>
|
||||
</ul>
|
||||
<li><a href="Python.html#Python_nn53">Typemaps</a>
|
||||
<ul>
|
||||
|
|
@ -1501,6 +1515,7 @@
|
|||
<ul>
|
||||
<li><a href="Tcl.html#Tcl_nn45">Proxy classes</a>
|
||||
</ul>
|
||||
<li><a href="Tcl.html#Tcl_nn46">Tcl/Tk Stubs</a>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
|
@ -1564,7 +1579,7 @@
|
|||
<li><a href="Extending.html#Extending_nn31">Writing a Language Module</a>
|
||||
<ul>
|
||||
<li><a href="Extending.html#Extending_nn32">Execution model</a>
|
||||
<li><a href="Extending.html#Extending_nn33">Starting out</a>
|
||||
<li><a href="Extending.html#Extending_starting_out">Starting out</a>
|
||||
<li><a href="Extending.html#Extending_nn34">Command line options</a>
|
||||
<li><a href="Extending.html#Extending_nn35">Configuration and preprocessing</a>
|
||||
<li><a href="Extending.html#Extending_nn36">Entry point to code generation</a>
|
||||
|
|
@ -1573,16 +1588,18 @@
|
|||
<li><a href="Extending.html#Extending_nn39">Configuration files</a>
|
||||
<li><a href="Extending.html#Extending_nn40">Runtime support</a>
|
||||
<li><a href="Extending.html#Extending_nn41">Standard library files</a>
|
||||
<li><a href="Extending.html#Extending_nn42">Examples and test cases</a>
|
||||
<li><a href="Extending.html#Extending_nn42">User examples</a>
|
||||
<li><a href="Extending.html#Extending_test_suite">Test driven development and the test-suite</a>
|
||||
<ul>
|
||||
<li><a href="Extending.html#Extending_running_test_suite">Running the test-suite</a>
|
||||
</ul>
|
||||
<li><a href="Extending.html#Extending_nn43">Documentation</a>
|
||||
<li><a href="Extending.html#Extending_prerequisites">Prerequisites for adding a new language module to the SWIG distribution</a>
|
||||
<li><a href="Extending.html#Extending_coding_style_guidelines">Coding style guidelines</a>
|
||||
</ul>
|
||||
<li><a href="Extending.html#Extending_nn44">Typemaps</a>
|
||||
<ul>
|
||||
<li><a href="Extending.html#Extending_nn45">Proxy classes</a>
|
||||
</ul>
|
||||
<li><a href="Extending.html#Extending_debugging_options">Debugging Options</a>
|
||||
<li><a href="Extending.html#Extending_nn46">Guide to parse tree nodes</a>
|
||||
<li><a href="Extending.html#Extending_further_info">Further Development Information</a>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
|
|
|||
|
|
@ -53,6 +53,21 @@ The <tt>%exception</tt> directive allows you to define a general purpose excepti
|
|||
handler. For example, you can specify the following:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%exception {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (RangeError) {
|
||||
... handle error ...
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
How the exception is handled depends on the target language, for example, Python:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%exception {
|
||||
try {
|
||||
|
|
@ -60,7 +75,7 @@ handler. For example, you can specify the following:
|
|||
}
|
||||
catch (RangeError) {
|
||||
PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
|
||||
return NULL;
|
||||
SWIG_fail;
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
<li><a href="#Extending_nn31">Writing a Language Module</a>
|
||||
<ul>
|
||||
<li><a href="#Extending_nn32">Execution model</a>
|
||||
<li><a href="#Extending_nn33">Starting out</a>
|
||||
<li><a href="#Extending_starting_out">Starting out</a>
|
||||
<li><a href="#Extending_nn34">Command line options</a>
|
||||
<li><a href="#Extending_nn35">Configuration and preprocessing</a>
|
||||
<li><a href="#Extending_nn36">Entry point to code generation</a>
|
||||
|
|
@ -57,16 +57,18 @@
|
|||
<li><a href="#Extending_nn39">Configuration files</a>
|
||||
<li><a href="#Extending_nn40">Runtime support</a>
|
||||
<li><a href="#Extending_nn41">Standard library files</a>
|
||||
<li><a href="#Extending_nn42">Examples and test cases</a>
|
||||
<li><a href="#Extending_nn42">User examples</a>
|
||||
<li><a href="#Extending_test_suite">Test driven development and the test-suite</a>
|
||||
<ul>
|
||||
<li><a href="#Extending_running_test_suite">Running the test-suite</a>
|
||||
</ul>
|
||||
<li><a href="#Extending_nn43">Documentation</a>
|
||||
<li><a href="#Extending_prerequisites">Prerequisites for adding a new language module to the SWIG distribution</a>
|
||||
<li><a href="#Extending_coding_style_guidelines">Coding style guidelines</a>
|
||||
</ul>
|
||||
<li><a href="#Extending_nn44">Typemaps</a>
|
||||
<ul>
|
||||
<li><a href="#Extending_nn45">Proxy classes</a>
|
||||
</ul>
|
||||
<li><a href="#Extending_debugging_options">Debugging Options</a>
|
||||
<li><a href="#Extending_nn46">Guide to parse tree nodes</a>
|
||||
<li><a href="#Extending_further_info">Further Development Information</a>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
|
@ -1025,7 +1027,7 @@ Deletes <tt>s</tt>.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>int Len(String_or_char *s)</tt></b>
|
||||
<b><tt>int Len(const String_or_char *s)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1033,7 +1035,7 @@ Returns the length of the string.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>char *Char(String_or_char *s)</tt></b>
|
||||
<b><tt>char *Char(const String_or_char *s)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1041,7 +1043,7 @@ Returns a pointer to the first character in a string.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>void Append(String *s, String_or_char *t)</tt></b>
|
||||
<b><tt>void Append(String *s, const String_or_char *t)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1049,7 +1051,7 @@ Appends <tt>t</tt> to the end of string <tt>s</tt>.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>void Insert(String *s, int pos, String_or_char *t)</tt></b>
|
||||
<b><tt>void Insert(String *s, int pos, const String_or_char *t)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1162,7 +1164,7 @@ Returns the number of items in <tt>h</tt>.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>Object *Getattr(Hash *h, String_or_char *key)</tt></b>
|
||||
<b><tt>Object *Getattr(Hash *h, const String_or_char *key)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1171,7 +1173,7 @@ a simple <tt>char *</tt> string. Returns NULL if not found.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>int Setattr(Hash *h, String_or_char *key, Object_or_char *val)</tt></b>
|
||||
<b><tt>int Setattr(Hash *h, const String_or_char *key, const Object_or_char *val)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1185,7 +1187,7 @@ of <tt>val</tt>. Returns 1 if this operation replaced an existing hash entry,
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>int Delattr(Hash *h, String_or_char *key)</tt></b>
|
||||
<b><tt>int Delattr(Hash *h, const String_or_char *key)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1249,7 +1251,7 @@ negative, the first item is returned.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>int *Setitem(List *x, int n, Object_or_char *val)</tt></b>
|
||||
<b><tt>int *Setitem(List *x, int n, const Object_or_char *val)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1271,7 +1273,7 @@ for <tt>n</tt>.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>void Append(List *x, Object_or_char *t)</tt></b>
|
||||
<b><tt>void Append(List *x, const Object_or_char *t)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1281,7 +1283,7 @@ used to create a String object.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>void Insert(String *s, int pos, Object_or_char *t)</tt></b>
|
||||
<b><tt>void Insert(String *s, int pos, const Object_or_char *t)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1479,13 +1481,14 @@ Same as the C <tt>tell()</tt> function.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>File *NewFile(const char *filename, const char *mode)</tt></b>
|
||||
<b><tt>File *NewFile(const char *filename, const char *mode, List *newfiles)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
Create a File object using the <tt>fopen()</tt> library call. This
|
||||
file differs from <tt>FILE *</tt> in that it can be placed in the standard
|
||||
SWIG containers (lists, hashes, etc.).
|
||||
SWIG containers (lists, hashes, etc.). The <tt>filename</tt> is added to the
|
||||
<tt>newfiles</tt> list if <tt>newfiles</tt> is non-zero and the file was created successfully.
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1922,7 +1925,7 @@ Adds a reference to <tt>ty</tt>.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>void SwigType_add_array(SwigType *ty, String_or_char *dim)</tt></b>
|
||||
<b><tt>void SwigType_add_array(SwigType *ty, const String_or_char *size)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1962,7 +1965,7 @@ Sets <tt>n</tt>th array dimensions of <tt>ty</tt> to <tt>rep</tt>.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>void SwigType_add_qualifier(SwigType *ty, String_or_char *q)</tt></b>
|
||||
<b><tt>void SwigType_add_qualifier(SwigType *ty, const String_or_char *q)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -1971,7 +1974,7 @@ Adds a type qualifier <tt>q</tt> to <tt>ty</tt>. <tt>q</tt> is typically
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>void SwigType_add_memberpointer(SwigType *ty, String_or_char *cls)</tt></b>
|
||||
<b><tt>void SwigType_add_memberpointer(SwigType *ty, const String_or_char *cls)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -2292,7 +2295,7 @@ The following functions produce strings that are suitable for output.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<b><tt>String *SwigType_str(SwigType *ty, String_or_char *id = 0)</tt></b>
|
||||
<b><tt>String *SwigType_str(SwigType *ty, const String_or_char *id = 0)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -2303,7 +2306,7 @@ used to convert string-encoded types back into a form that is valid C syntax.
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>String *SwigType_lstr(SwigType *ty, String_or_char *id = 0)</tt></b>
|
||||
<b><tt>String *SwigType_lstr(SwigType *ty, const String_or_char *id = 0)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -2312,7 +2315,7 @@ is generated from the type's lvalue (as generated from SwigType_ltype).
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>String *SwigType_lcaststr(SwigType *ty, String_or_char *id = 0)</tt></b>
|
||||
<b><tt>String *SwigType_lcaststr(SwigType *ty, const String_or_char *id = 0)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -2323,7 +2326,7 @@ this function produces the string "<tt>(char *) foo</tt>".
|
|||
</div>
|
||||
|
||||
<p>
|
||||
<b><tt>String *SwigType_rcaststr(SwigType *ty, String_or_char *id = 0)</tt></b>
|
||||
<b><tt>String *SwigType_rcaststr(SwigType *ty, const String_or_char *id = 0)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent">
|
||||
|
|
@ -2470,7 +2473,7 @@ the parsing of command line options, all aspects of code generation are controll
|
|||
different methods of the <tt>Language</tt> that must be defined by your module.
|
||||
</p>
|
||||
|
||||
<H3><a name="Extending_nn33"></a>35.10.2 Starting out</H3>
|
||||
<H3><a name="Extending_starting_out"></a>35.10.2 Starting out</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -2601,24 +2604,24 @@ void Language::main(int argc, char *argv[]) {
|
|||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if (strcmp(argv[i],"-globals") == 0) {
|
||||
if (argv[i+1]) {
|
||||
global_name = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if ( (strcmp(argv[i],"-proxy") == 0)) {
|
||||
proxy_flag = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-keyword") == 0) {
|
||||
use_kw = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-help") == 0) {
|
||||
fputs(usage,stderr);
|
||||
}
|
||||
} else if (strcmp(argv[i],"-globals") == 0) {
|
||||
if (argv[i+1]) {
|
||||
global_name = NewString(argv[i+1]);
|
||||
Swig_mark_arg(i);
|
||||
Swig_mark_arg(i+1);
|
||||
i++;
|
||||
} else {
|
||||
Swig_arg_error();
|
||||
}
|
||||
} else if ( (strcmp(argv[i],"-proxy") == 0)) {
|
||||
proxy_flag = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-keyword") == 0) {
|
||||
use_kw = 1;
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-help") == 0) {
|
||||
fputs(usage,stderr);
|
||||
}
|
||||
...
|
||||
}
|
||||
}
|
||||
|
|
@ -2776,6 +2779,7 @@ such as:
|
|||
class PYTHON : public Language {
|
||||
protected:
|
||||
/* General DOH objects used for holding the strings */
|
||||
File *f_begin;
|
||||
File *f_runtime;
|
||||
File *f_header;
|
||||
File *f_wrappers;
|
||||
|
|
@ -2791,22 +2795,25 @@ int Python::top(Node *n) {
|
|||
...
|
||||
|
||||
/* Initialize I/O */
|
||||
f_runtime = NewFile(outfile, "w");
|
||||
if (!f_runtime) {
|
||||
f_begin = NewFile(outfile, "w", SWIG_output_files());
|
||||
if (!f_begin) {
|
||||
FileErrorDisplay(outfile);
|
||||
SWIG_exit(EXIT_FAILURE);
|
||||
}
|
||||
f_runtime = NewString("");
|
||||
f_init = NewString("");
|
||||
f_header = NewString("");
|
||||
f_wrappers = NewString("");
|
||||
|
||||
/* Register file targets with the SWIG file handler */
|
||||
Swig_register_filebyname("begin", f_begin);
|
||||
Swig_register_filebyname("header", f_header);
|
||||
Swig_register_filebyname("wrapper", f_wrappers);
|
||||
Swig_register_filebyname("runtime", f_runtime);
|
||||
Swig_register_filebyname("init", f_init);
|
||||
|
||||
/* Output module initialization code */
|
||||
Swig_banner(f_begin);
|
||||
...
|
||||
|
||||
/* Emit code for children */
|
||||
|
|
@ -2814,16 +2821,18 @@ int Python::top(Node *n) {
|
|||
|
||||
...
|
||||
/* Write all to the file */
|
||||
Dump(f_header, f_runtime);
|
||||
Dump(f_wrappers, f_runtime);
|
||||
Wrapper_pretty_print(f_init, f_runtime);
|
||||
Dump(f_runtime, f_begin);
|
||||
Dump(f_header, f_begin);
|
||||
Dump(f_wrappers, f_begin);
|
||||
Wrapper_pretty_print(f_init, f_begin);
|
||||
|
||||
/* Cleanup files */
|
||||
Delete(f_runtime);
|
||||
Delete(f_header);
|
||||
Delete(f_wrappers);
|
||||
Delete(f_init);
|
||||
Close(f_runtime);
|
||||
Delete(f_runtime);
|
||||
Close(f_begin);
|
||||
Delete(f_begin);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
|
@ -3046,7 +3055,7 @@ but without the typemaps, there is still work to do.
|
|||
<!-- please report bugs in this section to ttn -->
|
||||
|
||||
<p>
|
||||
At the time of this writing, SWIG supports nearly a dozen languages,
|
||||
At the time of this writing, SWIG supports nearly twenty languages,
|
||||
which means that for continued sanity in maintaining the configuration
|
||||
files, the language modules need to follow some conventions. These are
|
||||
outlined here along with the admission that, yes it is ok to violate
|
||||
|
|
@ -3218,7 +3227,7 @@ The following are the minimum that are usually supported:
|
|||
Please copy these and modify for any new language.
|
||||
</p>
|
||||
|
||||
<H3><a name="Extending_nn42"></a>35.10.11 Examples and test cases</H3>
|
||||
<H3><a name="Extending_nn42"></a>35.10.11 User examples</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -3247,7 +3256,226 @@ during this process, see the section on <a href="#n37a">configuration
|
|||
files</a>.
|
||||
</p>
|
||||
|
||||
<H3><a name="Extending_nn43"></a>35.10.12 Documentation</H3>
|
||||
<H3><a name="Extending_test_suite"></a>35.10.12 Test driven development and the test-suite</H3>
|
||||
|
||||
|
||||
<p>
|
||||
A test driven development approach is central to the improvement and development of SWIG.
|
||||
Most modifications to SWIG are accompanied by additional regression tests and checking all
|
||||
tests to ensure that no regressions have been introduced.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The regression testing is carried out by the SWIG <i>test-suite</i>.
|
||||
The test-suite consists of numerous testcase interface files in the <tt>Examples/test-suite</tt> directory
|
||||
as well as target language specific runtime tests in the <tt>Examples/test-suite/[lang]</tt> directory.
|
||||
When a testcase is run, it will execute the following steps for each testcase:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>Execute SWIG passing it the testcase interface file.</li>
|
||||
<li>Compile the resulting generated C/C++ code with either the C or C++ compiler into object files.</li>
|
||||
<li>Link the object files into a dynamic library (dll/shared object).</li>
|
||||
<li>Compile any generated and any runtime test target language code with the target language compiler, if the target language supports compilation. This step thus does not apply to the interpreted languages.</li>
|
||||
<li>Execute a runtime test if one exists.</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
For example, the <i>ret_by_value</i> testcase consists of two components.
|
||||
The first component is the <tt>Examples/test-suite/ret_by_value.i</tt> interface file.
|
||||
The name of the SWIG module <b>must</b> always be the name of the testcase, so the <tt>ret_by_value.i</tt> interface file thus begins with:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%module ret_by_value
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The testcase code will then follow the module declaration,
|
||||
usually within a <tt>%inline %{ ... %}</tt> section for the majority of the tests.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The second component is the optional runtime tests.
|
||||
Any runtime tests are named using the following convention: <tt>[testcase]_runme.[ext]</tt>,
|
||||
where <tt>[testcase]</tt> is the testcase name and <tt>[ext]</tt> is the normal extension for the target language file.
|
||||
In this case, the Java and Python target languages implement a runtime test, so their files are respectively,
|
||||
<tt>Examples/test-suite/java/ret_by_value_runme.java</tt> and
|
||||
<tt>Examples/test-suite/python/ret_by_value_runme.py</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The goal of the test-suite is to test as much as possible in a <b>silent</b> manner.
|
||||
This way any SWIG or compiler errors or warnings are easily visible.
|
||||
Should there be any warnings, changes must be made to either fix them (preferably) or suppress them.
|
||||
Compilation or runtime errors result in a testcase failure and will be immediately visible.
|
||||
It is therefore essential that the runtime tests are written in a manner that displays nothing to stdout/stderr on success
|
||||
but error/exception out with an error message on stderr on failure.
|
||||
</p>
|
||||
|
||||
<H4><a name="Extending_running_test_suite"></a>35.10.12.1 Running the test-suite</H4>
|
||||
|
||||
|
||||
<p>
|
||||
In order for the test-suite to work for a particular target language, the language must be correctly detected
|
||||
and configured during the configure stage so that the correct Makefiles are generated.
|
||||
Most development occurs on Linux, so usually it is a matter of installing the development packages for the target language
|
||||
and simply configuring as outlined <a href="#Extending_starting_out">earlier</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If when running the test-suite commands that follow, you get a message that the test was skipped, it indicates that the
|
||||
configure stage is missing information in order to compile and run everything for that language.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The test-suite can be run in a number of ways.
|
||||
The first group of commands are for running multiple testcases in one run and should be executed in the top level directory.
|
||||
To run the entire test-suite (can take a long time):
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
make -k check-test-suite
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
To run the test-suite just for target language [lang], replace [lang] with one of csharp, java, perl5, python, ruby, tcl etc:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
make check-[lang]-test-suite
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Note that if a runtime test is available, a message "(with run test)" is displayed when run. For example:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
$ make check-python-test-suite
|
||||
checking python test-suite
|
||||
checking testcase argcargvtest (with run test) under python
|
||||
checking testcase python_autodoc under python
|
||||
checking testcase python_append (with run test) under python
|
||||
checking testcase callback (with run test) under python
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The files generated on a previous run can be deleted using the clean targets, either the whole test-suite or for a particular language:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
make clean-test-suite
|
||||
make clean-[lang]-test-suite
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The test-suite can be run in a <i>partialcheck</i> mode where just SWIG is executed, that is, the compile,
|
||||
link and running of the testcases is not performed.
|
||||
Note that the partialcheck does not require the target language to be correctly configured and detected and unlike the other test-suite make targets, is never skipped. Once again, either all the languages can be executed or just a chosen language:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
make partialcheck-test-suite
|
||||
make partialcheck-[lang]-test-suite
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
If your computer has more than one CPU, you are strongly advised to use parallel make to speed up the execution speed.
|
||||
This can be done with any of the make targets that execute more than one testcase.
|
||||
For example, a dual core processor can efficiently use 2 parallel jobs:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
make -j2 check-test-suite
|
||||
make -j2 check-python-test-suite
|
||||
make -j2 partialcheck-java-test-suite
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The second group of commands are for running individual testcases and should be executed in the appropriate
|
||||
target language directory, <tt>Examples/test-suite/[lang]</tt>.
|
||||
Testcases can contain either C or C++ code and when one is written, a decision must be made as to which of these input
|
||||
languages is to be used.
|
||||
Replace <tt>[testcase]</tt> in the commands below with the name of the testcase.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For a C language testcase, add the testcase under the C_TEST_CASES list in <tt>Examples/test-suite/common.mk</tt> and
|
||||
execute individually as:
|
||||
</p>
|
||||
<div class="shell"><pre>
|
||||
make -s [testcase].ctest
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
For a C++ language testcase, add the testcase under the CPP_TEST_CASES list in <tt>Examples/test-suite/common.mk</tt> and
|
||||
execute individually as:
|
||||
</p>
|
||||
<div class="shell"><pre>
|
||||
make -s [testcase].cpptest
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
A third category of tests are C++ language testcases testing multiple modules (the %import directive).
|
||||
These require more than one shared library (dll/shared object) to be built and so are separated out from the normal C++ testcases.
|
||||
Add the testcase under the MULTI_CPP_TEST_CASES list in <tt>Examples/test-suite/common.mk</tt> and
|
||||
execute individually as:
|
||||
</p>
|
||||
<div class="shell"><pre>
|
||||
make -s [testcase].multicpptest
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
To delete the generated files, execute:
|
||||
</p>
|
||||
<div class="shell"><pre>
|
||||
make -s [testcase].clean
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
If you would like to see the exact commands being executed, drop the -s option:
|
||||
</p>
|
||||
<div class="shell"><pre>
|
||||
make [testcase].ctest
|
||||
make [testcase].cpptest
|
||||
make [testcase].multicpptest
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Some real examples of each:
|
||||
</p>
|
||||
<div class="shell"><pre>
|
||||
make -s ret_by_value.clean
|
||||
make -s ret_by_value.ctest
|
||||
make -s bools.cpptest
|
||||
make -s imports.multicpptest
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Advanced usage of the test-suite facilitates running tools on some of the five stages.
|
||||
The make variables <tt>SWIGTOOL</tt> and <tt>RUNTOOL</tt> are used to specify a tool to respectively, invoke SWIG
|
||||
and the execution of the runtime test.
|
||||
You are advised to view the <tt>Examples/test-suite/common.mk</tt> file for details but for a short summary,
|
||||
the classic usage is to use <a href="http://valgrind.org/">Valgrind</a> for memory checking.
|
||||
For example, checking for memory leaks when running the runtime test in the target language interpreter:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
make ret_by_value.ctest RUNTOOL="valgrind --leak-check=full"
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
This will probably make more sense if you look at the output of the above as it will show the exact commands being executed.
|
||||
SWIG can be analyzed for bad memory accesses using:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
make ret_by_value.ctest SWIGTOOL="valgrind --tool=memcheck --trace-children=yes"
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Extending_nn43"></a>35.10.13 Documentation</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -3279,7 +3507,7 @@ Some topics that you'll want to be sure to address include:
|
|||
if available.
|
||||
</ul>
|
||||
|
||||
<H3><a name="Extending_prerequisites"></a>35.10.13 Prerequisites for adding a new language module to the SWIG distribution</H3>
|
||||
<H3><a name="Extending_prerequisites"></a>35.10.14 Prerequisites for adding a new language module to the SWIG distribution</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -3336,7 +3564,7 @@ should be added should there be an area not already covered by
|
|||
the existing tests.
|
||||
</p>
|
||||
|
||||
<H3><a name="Extending_coding_style_guidelines"></a>35.10.14 Coding style guidelines</H3>
|
||||
<H3><a name="Extending_coding_style_guidelines"></a>35.10.15 Coding style guidelines</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -3360,11 +3588,30 @@ The generated C/C++ code should also follow this style as close as possible. How
|
|||
should be avoided as unlike the SWIG developers, users will never have consistent tab settings.
|
||||
</p>
|
||||
|
||||
<H2><a name="Extending_nn44"></a>35.11 Typemaps</H2>
|
||||
<H2><a name="Extending_debugging_options"></a>35.11 Debugging Options</H2>
|
||||
|
||||
|
||||
<H3><a name="Extending_nn45"></a>35.11.1 Proxy classes</H3>
|
||||
<p>
|
||||
There are various command line options which can aid debugging a SWIG interface as well as debugging the development of a language module. These are as follows:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
-debug-classes - Display information about the classes found in the interface
|
||||
-debug-module <n> - Display module parse tree at stages 1-4, <n> is a csv list of stages
|
||||
-debug-symtabs - Display symbol tables information
|
||||
-debug-symbols - Display target language symbols in the symbol tables
|
||||
-debug-csymbols - Display C symbols in the symbol tables
|
||||
-debug-lsymbols - Display target language layer symbols
|
||||
-debug-tags - Display information about the tags found in the interface
|
||||
-debug-template - Display information for debugging templates
|
||||
-debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages
|
||||
-debug-typedef - Display information about the types and typedefs in the interface
|
||||
-debug-typemap - Display information for debugging typemaps
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The complete list of command line options for SWIG are available by running <tt>swig -help</tt>.
|
||||
</p>
|
||||
|
||||
<H2><a name="Extending_nn46"></a>35.12 Guide to parse tree nodes</H2>
|
||||
|
||||
|
|
@ -3774,6 +4021,13 @@ extern "X" { ... } declaration.
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<H2><a name="Extending_further_info"></a>35.13 Further Development Information</H2>
|
||||
|
||||
|
||||
<p>
|
||||
There is further documentation available on the internals of SWIG, API documentation and debugging information.
|
||||
This is shipped with SWIG in the <tt>Doc/Devel</tt> directory.
|
||||
</P>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -814,7 +814,7 @@ Produces the following code at the top of the generated GOOPS guile-module
|
|||
<code>Module-primitive.scm</code> (with <i>primitive</i> replaced with whatever is given with the <code>-primsuffix</code>
|
||||
argument. The code to load the <code>.so</code> library should be located in the <code>%scheme</code> directive,
|
||||
which will then be added to the scmstub file.
|
||||
Swig will automatically generate the line <code>(use-modules (<i>Package</i> <i>Module-primitive</i>))</code>
|
||||
SWIG will automatically generate the line <code>(use-modules (<i>Package</i> <i>Module-primitive</i>))</code>
|
||||
into the GOOPS guile-module. So if <i>Module-primitive.scm</i> is on the autoload path for guile, the
|
||||
<code>%goops</code> directive can be empty. Otherwise, the <code>%goops</code> directive should contain
|
||||
whatever code is needed to load the <i>Module-primitive.scm</i> file into guile.</p>
|
||||
|
|
@ -848,7 +848,7 @@ Produces the following code at the top of the generated GOOPS guile-module
|
|||
</li>
|
||||
|
||||
<li><p><b>Module Linkage</b>: This is very similar to passive linkage with a scmstub file.
|
||||
Swig will also automatically generate the line <code>(use-modules
|
||||
SWIG will also automatically generate the line <code>(use-modules
|
||||
(<i>Package</i> <i>Module-primitive</i>))</code> into the GOOPS guile-module. Again the <code>%goops</code>
|
||||
directive should contain whatever code is needed to get that module loaded into guile.</p>
|
||||
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ major features include:
|
|||
|
||||
<p>
|
||||
Currently, the only major C++ feature not supported is nested classes--a limitation
|
||||
that will be removed in a future release.
|
||||
that should be removed in a future release, but has some workarounds for the moment.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -253,6 +253,12 @@ To change this, you can use the <tt>-o</tt> option.
|
|||
It is also possible to change the <a href="SWIG.html#output">output directory </a> that the Java files are generated into using <tt>-outdir</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The module name, specified with <tt>%module</tt>, determines the name of various generated classes as discussed <a href=#module_packages_classes>later</a>.
|
||||
Note that the module name does not define a Java package and by default, the generated Java classes do not have a Java package.
|
||||
The <tt>-package</tt> option described below can specify a Java package name to use.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following sections have further practical examples and details on how you might go about
|
||||
compiling and using the generated files.
|
||||
|
|
@ -441,6 +447,19 @@ $
|
|||
<p>
|
||||
This error usually indicates that you forgot to include some object files or libraries in the linking of the native library file.
|
||||
Make sure you compile both the SWIG wrapper file and the code you are wrapping into the native library file.
|
||||
If you forget to compile and link in the SWIG wrapper file into your native library file, you will get a message similar to the following:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
$ java runme
|
||||
Exception in thread "main" java.lang.UnsatisfiedLinkError: exampleJNI.gcd(II)I
|
||||
at exampleJNI.gcd(Native Method)
|
||||
at example.gcd(example.java:12)
|
||||
at runme.main(runme.java:18)
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
where <tt>gcd</tt> is the missing JNI function that SWIG generated into the wrapper file.
|
||||
Also make sure you pass all of the required libraries to the linker.
|
||||
The <tt>java -verbose:jni</tt> commandline switch is also a great way to get more information on unresolved symbols.
|
||||
One last piece of advice is to beware of the common faux pas of having more than one native library version in your path.
|
||||
|
|
@ -657,7 +676,9 @@ This is often combined with the <tt>-outdir</tt> to specify a package directory
|
|||
swig -java -package com.bloggs.swig -outdir com/bloggs/swig example.i
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
SWIG won't create the directory, so make sure it exists beforehand.
|
||||
</p>
|
||||
|
||||
<H3><a name="functions"></a>21.3.2 Functions</H3>
|
||||
|
||||
|
|
@ -1753,7 +1774,7 @@ If declarations such as these appear, you will get a warning message like this:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
example.i:12: Warning(515): Overloaded method spam(unsigned short) ignored.
|
||||
example.i:12: Warning 515: Overloaded method spam(unsigned short) ignored.
|
||||
Method spam(int) at example.i:11 used.
|
||||
</pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -667,7 +667,7 @@ in order for this to work.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<b><tt>char *cdata(void *ptr, int nbytes)</tt></b>
|
||||
<b><tt>const char *cdata(void *ptr, size_t nbytes)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent"><p>
|
||||
|
|
@ -676,7 +676,7 @@ pointer.
|
|||
</p></div>
|
||||
|
||||
<p>
|
||||
<b><tt>void memmove(void *ptr, char *s)</tt></b>
|
||||
<b><tt>void memmove(void *ptr, const char *s)</tt></b>
|
||||
</p>
|
||||
|
||||
<div class="indent"><p>
|
||||
|
|
@ -890,7 +890,10 @@ char *foo();
|
|||
</div>
|
||||
|
||||
<p>
|
||||
This will release the result.
|
||||
This will release the result if the appropriate target language support is available.
|
||||
SWIG provides the appropriate "newfree" typemap for <tt>char *</tt> so that the memory is released,
|
||||
however, you may need to provide your own "newfree" typemap for other types.
|
||||
See <a href="Customization.html#ownership">Object ownership and %newobject</a> for more details.
|
||||
</p>
|
||||
|
||||
<H3><a name="Library_nn12"></a>8.3.4 cstring.i</H3>
|
||||
|
|
|
|||
|
|
@ -684,8 +684,8 @@ void foo(Bar &b);
|
|||
If declarations such as these appear, you will get a warning message like this:
|
||||
</p>
|
||||
<div class="shell"><pre>
|
||||
example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int)
|
||||
at example.i:11.
|
||||
example.i:12: Warning 509: Overloaded method spam(short) effectively ignored,
|
||||
example.i:11: Warning 509: as it is shadowed by spam(int).
|
||||
</pre></div>
|
||||
<p>
|
||||
To fix this, you either need to ignore or rename one of the methods. For example:
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
<!-- INDEX -->
|
||||
<div class="sectiontoc">
|
||||
<ul>
|
||||
<li><a href="#Modules_introduction">Modules Introduction</a>
|
||||
<li><a href="#Modules_nn1">Basics</a>
|
||||
<li><a href="#Modules_nn2">The SWIG runtime code</a>
|
||||
<li><a href="#external_run_time">External access to the runtime</a>
|
||||
|
|
@ -22,11 +23,49 @@
|
|||
|
||||
|
||||
|
||||
<H2><a name="Modules_introduction"></a>15.1 Modules Introduction</H2>
|
||||
|
||||
|
||||
<p>
|
||||
Each invocation of SWIG requires a module name to be specified.
|
||||
The module name is used to name the resulting target language extension module.
|
||||
Exactly what this means and and what the name is used for
|
||||
depends on the target language, for example the name can define
|
||||
a target language namespace or merely be a useful name for naming files or helper classes.
|
||||
Essentially, a module comprises target language wrappers for a chosen collection of global variables/functions, structs/classes and other C/C++ types.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The module name can be supplied in one of two ways.
|
||||
The first is to specify it with the special <tt>%module</tt>
|
||||
directive. This directive must appear at the beginning of the interface file.
|
||||
The general form of this directive is:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
<tt>%module(option1="value1",option2="value2",...) modulename</tt>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
where the modulename is mandatory and the options add one or more optional additional features.
|
||||
Typically no options are specified, for example:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
<tt>%module mymodule</tt>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The second way to specify the module name is with the <tt>-module</tt> command line option, for example <tt>-module mymodule</tt>.
|
||||
If the module name is supplied on the command line, it overrides the name specified by the
|
||||
<tt>%module</tt> directive.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When first working with SWIG, users commonly start by creating a
|
||||
single module. That is, you might define a single SWIG interface that
|
||||
wraps some set of C/C++ code. You then compile all of the generated
|
||||
wrapper code into a module and use it. For large applications, however,
|
||||
wrapper code together and use it. For large applications, however,
|
||||
this approach is problematic---the size of the generated wrapper code
|
||||
can be rather large. Moreover, it is probably easier to manage the
|
||||
target language interface when it is broken up into smaller pieces.
|
||||
|
|
@ -34,10 +73,11 @@ target language interface when it is broken up into smaller pieces.
|
|||
|
||||
<p>
|
||||
This chapter describes the problem of using SWIG in programs
|
||||
where you want to create a collection of modules.
|
||||
where you want to create a collection of modules.
|
||||
Each module in the collection is created via separate invocations of SWIG.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modules_nn1"></a>15.1 Basics</H2>
|
||||
<H2><a name="Modules_nn1"></a>15.2 Basics</H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -98,7 +138,7 @@ base class's methods. Typically you will get a warning when the module name is m
|
|||
</p>
|
||||
|
||||
<div class="shell"> <pre>
|
||||
derived_module.i:8: Warning(401): Base class 'base' ignored - unknown module name for base. Either import
|
||||
derived_module.i:8: Warning 401: Base class 'base' ignored - unknown module name for base. Either import
|
||||
the appropriate module interface file or specify the name of the module in the %import directive.
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -135,7 +175,7 @@ in parallel from multiple threads as SWIG provides no locking - for more on that
|
|||
issue, read on.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modules_nn2"></a>15.2 The SWIG runtime code</H2>
|
||||
<H2><a name="Modules_nn2"></a>15.3 The SWIG runtime code</H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -201,7 +241,7 @@ can peacefully coexist. So the type structures are separated by the
|
|||
is empty. Only modules compiled with the same pair will share type information.
|
||||
</p>
|
||||
|
||||
<H2><a name="external_run_time"></a>15.3 External access to the runtime</H2>
|
||||
<H2><a name="external_run_time"></a>15.4 External access to the runtime</H2>
|
||||
|
||||
|
||||
<p>As described in <a href="Typemaps.html#runtime_type_checker">The run-time type checker</a>,
|
||||
|
|
@ -238,7 +278,7 @@ SWIG_TYPE_TABLE to be the same as the module whose types you are trying to
|
|||
access.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modules_nn4"></a>15.4 A word of caution about static libraries</H2>
|
||||
<H2><a name="Modules_nn4"></a>15.5 A word of caution about static libraries</H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -249,7 +289,7 @@ into it. This is very often <b>NOT</b> what you want and it can lead to unexpect
|
|||
behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libraries.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modules_nn5"></a>15.5 References</H2>
|
||||
<H2><a name="Modules_nn5"></a>15.6 References</H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -257,7 +297,7 @@ Due to the complexity of working with shared libraries and multiple modules, it
|
|||
an outside reference. John Levine's "Linkers and Loaders" is highly recommended.
|
||||
</p>
|
||||
|
||||
<H2><a name="Modules_nn6"></a>15.6 Reducing the wrapper file size</H2>
|
||||
<H2><a name="Modules_nn6"></a>15.7 Reducing the wrapper file size</H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -634,13 +634,13 @@ length. Instead, use multiple returns, as in the argout_ref example.
|
|||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include stl.i
|
||||
%include <stl.i>
|
||||
|
||||
namespace std {
|
||||
%template(StringVector) std::vector < string >;
|
||||
};
|
||||
|
||||
%include example.h
|
||||
%include "example.h"
|
||||
</pre></td></tr>
|
||||
<tr><td><font size="-1"><i>This example is in Examples/ocaml/stl
|
||||
</i></font></td></tr>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
<li><a href="#Perl5_nn24">Modules and packages</a>
|
||||
</ul>
|
||||
<li><a href="#Perl5_nn25">Input and output parameters</a>
|
||||
<li><a href="#Perl5_nn26">Exception handling </a>
|
||||
<li><a href="#Perl5_nn26">Exception handling</a>
|
||||
<li><a href="#Perl5_nn27">Remapping datatypes with typemaps</a>
|
||||
<ul>
|
||||
<li><a href="#Perl5_nn28">A simple typemap example</a>
|
||||
|
|
@ -50,8 +50,8 @@
|
|||
</ul>
|
||||
<li><a href="#Perl5_nn32">Typemap Examples</a>
|
||||
<ul>
|
||||
<li><a href="#Perl5_nn33">Converting a Perl5 array to a char ** </a>
|
||||
<li><a href="#Perl5_nn34">Return values </a>
|
||||
<li><a href="#Perl5_nn33">Converting a Perl5 array to a char **</a>
|
||||
<li><a href="#Perl5_nn34">Return values</a>
|
||||
<li><a href="#Perl5_nn35">Returning values from arguments</a>
|
||||
<li><a href="#Perl5_nn36">Accessing array structure members</a>
|
||||
<li><a href="#Perl5_nn37">Turning Perl references into C pointers</a>
|
||||
|
|
@ -112,7 +112,7 @@ options are found near the end of the chapter.
|
|||
|
||||
|
||||
<p>
|
||||
To build a Perl5 module, run Swig using the <tt>-perl</tt> option as
|
||||
To build a Perl5 module, run SWIG using the <tt>-perl</tt> option as
|
||||
follows :
|
||||
</p>
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ extern int fact(int);
|
|||
%}
|
||||
|
||||
// Include code for rebuilding Perl
|
||||
%include perlmain.i
|
||||
%include <perlmain.i>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -815,7 +815,7 @@ extern char *path; // Declared later in the input
|
|||
|
||||
|
||||
<p>
|
||||
Constants are wrapped as read-only Perl variables. For example:
|
||||
By default, constants are wrapped as read-only Perl variables. For example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -838,6 +838,19 @@ $example::FOO = 2; # Error
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Alternatively, if you use swig's <tt>-const</tt> option, constants are wrapped
|
||||
such that the leading $ isn't required (by using a constant subroutine), which
|
||||
usually gives a more natural Perl interface, for example:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
use example;
|
||||
print example::FOO,"\n";
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H3><a name="Perl5_nn18"></a>28.4.4 Pointers</H3>
|
||||
|
||||
|
||||
|
|
@ -879,7 +892,7 @@ if (defined($ptr)) {
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
To create a NULL pointer, you should pass the <tt>undef </tt>value to
|
||||
To create a NULL pointer, you should pass the <tt>undef</tt> value to
|
||||
a function.
|
||||
</p>
|
||||
|
||||
|
|
@ -889,7 +902,7 @@ pointer that SWIG wrapper functions return. Suppose that <tt>$a</tt>
|
|||
and <tt>$b</tt> are two references that point to the same C object.
|
||||
In general, <tt>$a</tt> and <tt>$b</tt> will be different--since they
|
||||
are different references. Thus, it is a mistake to check the equality
|
||||
of <tt>$a </tt>and <tt>$b</tt> to check the equality of two C
|
||||
of <tt>$a</tt> and <tt>$b</tt> to check the equality of two C
|
||||
pointers. The correct method to check equality of C pointers is to
|
||||
dereference them as follows :
|
||||
</p>
|
||||
|
|
@ -1543,7 +1556,7 @@ example:
|
|||
<div class="code">
|
||||
<pre>
|
||||
%module example
|
||||
%include typemaps.i
|
||||
%include "typemaps.i"
|
||||
|
||||
void add(int x, int y, int *REFERENCE);
|
||||
</pre>
|
||||
|
|
@ -1567,7 +1580,7 @@ print "$c\n";
|
|||
<b>Note:</b> The <tt>REFERENCE</tt> feature is only currently supported for numeric types (integers and floating point).
|
||||
</p>
|
||||
|
||||
<H2><a name="Perl5_nn26"></a>28.6 Exception handling </H2>
|
||||
<H2><a name="Perl5_nn26"></a>28.6 Exception handling</H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -2107,7 +2120,7 @@ might look at the files "<tt>perl5.swg</tt>" and "<tt>typemaps.i</tt>" in
|
|||
the SWIG library.
|
||||
</p>
|
||||
|
||||
<H3><a name="Perl5_nn33"></a>28.8.1 Converting a Perl5 array to a char ** </H3>
|
||||
<H3><a name="Perl5_nn33"></a>28.8.1 Converting a Perl5 array to a char **</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -2160,7 +2173,7 @@ reference to be used as a char ** datatype.
|
|||
};
|
||||
myav = av_make(len,svs);
|
||||
free(svs);
|
||||
$result = newRV((SV*)myav);
|
||||
$result = newRV_noinc((SV*)myav);
|
||||
sv_2mortal($result);
|
||||
argvi++;
|
||||
}
|
||||
|
|
@ -2199,7 +2212,7 @@ print @$b,"\n"; # Print it out
|
|||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="Perl5_nn34"></a>28.8.2 Return values </H3>
|
||||
<H3><a name="Perl5_nn34"></a>28.8.2 Return values</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -2714,7 +2727,7 @@ corresponding Perl object (this situation turns out to come up
|
|||
frequently when constructing objects like linked lists and trees).
|
||||
When C takes possession of an object, you can change Perl's ownership
|
||||
by simply deleting the object from the <tt>%OWNER</tt> hash. This is
|
||||
done using the <tt>DISOWN </tt>method.
|
||||
done using the <tt>DISOWN</tt> method.
|
||||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
|
|
|
|||
|
|
@ -32,16 +32,22 @@
|
|||
</ul>
|
||||
<li><a href="#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</a>
|
||||
</ul>
|
||||
<li><a href="#Php_nn3">Cross language polymorphism</a>
|
||||
<ul>
|
||||
<li><a href="#Php_nn3_1">Enabling directors</a>
|
||||
<li><a href="#Php_nn3_2">Director classes</a>
|
||||
<li><a href="#Php_nn3_3">Ownership and object destruction</a>
|
||||
<li><a href="#Php_nn3_4">Exception unrolling</a>
|
||||
<li><a href="#Php_nn3_5">Overhead and code bloat</a>
|
||||
<li><a href="#Php_nn3_6">Typemaps</a>
|
||||
<li><a href="#Php_nn3_7">Miscellaneous</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
<b>Caution: This chapter (and module!) is still under construction</b>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
SWIG supports generating wrappers for PHP5. Support for PHP4 has been removed
|
||||
as of SWIG 1.3.37. The PHP developers are no longer making new PHP4 releases,
|
||||
|
|
@ -95,7 +101,7 @@ also contain PHP5 class wrappers.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
Swig can generate PHP extensions from C++ libraries as well when
|
||||
SWIG can generate PHP extensions from C++ libraries as well when
|
||||
given the <tt>-c++</tt> option. The support for C++ is discussed in
|
||||
more detail in <a href="#Php_nn2_6">section 27.2.6</a>.
|
||||
</p>
|
||||
|
|
@ -479,7 +485,7 @@ One can include <b>cpointer.i</b> to generate PHP wrappers to <tt>int
|
|||
|
||||
<div class="code"><pre>
|
||||
%module example
|
||||
%include cpointer.i
|
||||
%include "cpointer.i"
|
||||
%pointer_functions(int,intp)
|
||||
|
||||
void add( int *in1, int *in2, int *result);
|
||||
|
|
@ -513,7 +519,7 @@ parameter names as appropriate.
|
|||
|
||||
<div class="code"><pre>
|
||||
%module example
|
||||
%include typemaps.i
|
||||
%include "typemaps.i"
|
||||
|
||||
void add( int *INPUT, int *INPUT, int *OUTPUT);
|
||||
|
||||
|
|
@ -545,7 +551,7 @@ named typemap REFERENCE.
|
|||
|
||||
<div class="code"><pre>
|
||||
%module example
|
||||
%include phppointers.i
|
||||
%include "phppointers.i"
|
||||
|
||||
void add( int *REF, int *REF, int *REF);
|
||||
|
||||
|
|
@ -866,5 +872,381 @@ The <tt>%rinit</tt> and <tt>%rshutdown</tt> statements insert code
|
|||
into the request init and shutdown code respectively.
|
||||
</p>
|
||||
|
||||
<H2><a name="Php_nn3"></a>29.3 Cross language polymorphism</H2>
|
||||
|
||||
|
||||
<p>
|
||||
Proxy classes provide a more natural, object-oriented way to access
|
||||
extension classes. As described above, each proxy instance has an
|
||||
associated C++ instance, and method calls to the proxy are passed to the
|
||||
C++ instance transparently via C wrapper functions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This arrangement is asymmetric in the sense that no corresponding
|
||||
mechanism exists to pass method calls down the inheritance chain from
|
||||
C++ to PHP. In particular, if a C++ class has been extended in PHP
|
||||
(by extending the proxy class), these extensions will not be visible
|
||||
from C++ code. Virtual method calls from C++ are thus not able access
|
||||
the lowest implementation in the inheritance chain.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Changes have been made to SWIG 1.3.18 to address this problem and make
|
||||
the relationship between C++ classes and proxy classes more symmetric.
|
||||
To achieve this goal, new classes called directors are introduced at the
|
||||
bottom of the C++ inheritance chain. Support for generating PHP classes
|
||||
has been added in SWIG 1.3.40. The job of the directors is to route
|
||||
method calls correctly, either to C++ implementations higher in the
|
||||
inheritance chain or to PHP implementations lower in the inheritance
|
||||
chain. The upshot is that C++ classes can be extended in PHP and from
|
||||
C++ these extensions look exactly like native C++ classes. Neither C++
|
||||
code nor PHP code needs to know where a particular method is
|
||||
implemented: the combination of proxy classes, director classes, and C
|
||||
wrapper functions takes care of all the cross-language method routing
|
||||
transparently.
|
||||
</p>
|
||||
|
||||
<H3><a name="Php_nn3_1"></a>29.3.1 Enabling directors</H3>
|
||||
|
||||
|
||||
<p>
|
||||
The director feature is disabled by default. To use directors you
|
||||
must make two changes to the interface file. First, add the "directors"
|
||||
option to the %module directive, like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%module(directors="1") modulename
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Without this option no director code will be generated. Second, you
|
||||
must use the %feature("director") directive to tell SWIG which classes
|
||||
and methods should get directors. The %feature directive can be applied
|
||||
globally, to specific classes, and to specific methods, like this:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
// generate directors for all classes that have virtual methods
|
||||
%feature("director");
|
||||
|
||||
// generate directors for all virtual methods in class Foo
|
||||
%feature("director") Foo;
|
||||
|
||||
// generate a director for just Foo::bar()
|
||||
%feature("director") Foo::bar;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
You can use the %feature("nodirector") directive to turn off
|
||||
directors for specific classes or methods. So for example,
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("director") Foo;
|
||||
%feature("nodirector") Foo::bar;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
will generate directors for all virtual methods of class Foo except
|
||||
bar().
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Directors can also be generated implicitly through inheritance.
|
||||
In the following, class Bar will get a director class that handles
|
||||
the methods one() and two() (but not three()):
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("director") Foo;
|
||||
class Foo {
|
||||
public:
|
||||
Foo(int foo);
|
||||
virtual void one();
|
||||
virtual void two();
|
||||
};
|
||||
|
||||
class Bar: public Foo {
|
||||
public:
|
||||
virtual void three();
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
then at the PHP side you can define
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
require("mymodule.php");
|
||||
|
||||
class MyFoo extends Foo {
|
||||
function one() {
|
||||
print "one from php\n";
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
<H3><a name="Php_nn3_2"></a>29.3.2 Director classes</H3>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<p>
|
||||
For each class that has directors enabled, SWIG generates a new class
|
||||
that derives from both the class in question and a special
|
||||
<tt>Swig::Director</tt> class. These new classes, referred to as director
|
||||
classes, can be loosely thought of as the C++ equivalent of the PHP
|
||||
proxy classes. The director classes store a pointer to their underlying
|
||||
PHP object. Indeed, this is quite similar to the "_cPtr" and "thisown"
|
||||
members of the PHP proxy classes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For simplicity let's ignore the <tt>Swig::Director</tt> class and refer to the
|
||||
original C++ class as the director's base class. By default, a director
|
||||
class extends all virtual methods in the inheritance chain of its base
|
||||
class (see the preceding section for how to modify this behavior).
|
||||
Thus all virtual method calls, whether they originate in C++ or in
|
||||
PHP via proxy classes, eventually end up in at the implementation in the
|
||||
director class. The job of the director methods is to route these method
|
||||
calls to the appropriate place in the inheritance chain. By "appropriate
|
||||
place" we mean the method that would have been called if the C++ base
|
||||
class and its extensions in PHP were seamlessly integrated. That
|
||||
seamless integration is exactly what the director classes provide,
|
||||
transparently skipping over all the messy extension API glue that binds
|
||||
the two languages together.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In reality, the "appropriate place" is one of only two possibilities:
|
||||
C++ or PHP. Once this decision is made, the rest is fairly easy. If the
|
||||
correct implementation is in C++, then the lowest implementation of the
|
||||
method in the C++ inheritance chain is called explicitly. If the correct
|
||||
implementation is in PHP, the Zend API is used to call the method of the
|
||||
underlying PHP object (after which the usual virtual method resolution
|
||||
in PHP automatically finds the right implementation).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Now how does the director decide which language should handle the method call?
|
||||
The basic rule is to handle the method in PHP, unless there's a good
|
||||
reason not to. The reason for this is simple: PHP has the most
|
||||
"extended" implementation of the method. This assertion is guaranteed,
|
||||
since at a minimum the PHP proxy class implements the method. If the
|
||||
method in question has been extended by a class derived from the proxy
|
||||
class, that extended implementation will execute exactly as it should.
|
||||
If not, the proxy class will route the method call into a C wrapper
|
||||
function, expecting that the method will be resolved in C++. The wrapper
|
||||
will call the virtual method of the C++ instance, and since the director
|
||||
extends this the call will end up right back in the director method. Now
|
||||
comes the "good reason not to" part. If the director method were to blindly
|
||||
call the PHP method again, it would get stuck in an infinite loop. We avoid this
|
||||
situation by adding special code to the C wrapper function that tells
|
||||
the director method to not do this. The C wrapper function compares the
|
||||
called and the declaring class name of the given method. If these are
|
||||
not the same, then the C wrapper function tells the director to resolve
|
||||
the method by calling up the C++ inheritance chain, preventing an
|
||||
infinite loop.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
One more point needs to be made about the relationship between director
|
||||
classes and proxy classes. When a proxy class instance is created in
|
||||
PHP, SWIG creates an instance of the original C++ class and assigns it
|
||||
to <tt>->_cPtr</tt>. This is exactly what happens without directors
|
||||
and is true even if directors are enabled for the particular class in
|
||||
question. When a class <i>derived</i> from a proxy class is created,
|
||||
however, SWIG then creates an instance of the corresponding C++ director
|
||||
class. The reason for this difference is that user-defined subclasses
|
||||
may override or extend methods of the original class, so the director
|
||||
class is needed to route calls to these methods correctly. For
|
||||
unmodified proxy classes, all methods are ultimately implemented in C++
|
||||
so there is no need for the extra overhead involved with routing the
|
||||
calls through PHP.
|
||||
</p>
|
||||
|
||||
<H3><a name="Php_nn3_3"></a>29.3.3 Ownership and object destruction</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Memory management issues are slightly more complicated with directors
|
||||
than for proxy classes alone. PHP instances hold a pointer to the
|
||||
associated C++ director object, and the director in turn holds a pointer
|
||||
back to the PHP object. By default, proxy classes own their C++ director
|
||||
object and take care of deleting it when they are garbage collected.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This relationship can be reversed by calling the special
|
||||
<tt>->thisown</tt> property of the proxy class. After setting this
|
||||
property to <tt>0</tt>, the director class no longer destroys the PHP
|
||||
object. Assuming no outstanding references to the PHP object remain,
|
||||
the PHP object will be destroyed at the same time. This is a good thing,
|
||||
since directors and proxies refer to each other and so must be created
|
||||
and destroyed together. Destroying one without destroying the other will
|
||||
likely cause your program to segfault.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Here is an example:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class Foo {
|
||||
public:
|
||||
...
|
||||
};
|
||||
class FooContainer {
|
||||
public:
|
||||
void addFoo(Foo *);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
$c = new FooContainer();
|
||||
$a = new Foo();
|
||||
$a->thisown = 0;
|
||||
$c->addFoo($a);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
In this example, we are assuming that FooContainer will take care of
|
||||
deleting all the Foo pointers it contains at some point.
|
||||
</p>
|
||||
|
||||
<H3><a name="Php_nn3_4"></a>29.3.4 Exception unrolling</H3>
|
||||
|
||||
|
||||
<p>
|
||||
With directors routing method calls to PHP, and proxies routing them
|
||||
to C++, the handling of exceptions is an important concern. By default, the
|
||||
directors ignore exceptions that occur during method calls that are
|
||||
resolved in PHP. To handle such exceptions correctly, it is necessary
|
||||
to temporarily translate them into C++ exceptions. This can be done with
|
||||
the %feature("director:except") directive. The following code should
|
||||
suffice in most cases:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%feature("director:except") {
|
||||
if ($error == FAILURE) {
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This code will check the PHP error state after each method call from a
|
||||
director into PHP, and throw a C++ exception if an error occurred. This
|
||||
exception can be caught in C++ to implement an error handler.
|
||||
Currently no information about the PHP error is stored in the
|
||||
Swig::DirectorMethodException object, but this will likely change in the
|
||||
future.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It may be the case that a method call originates in PHP, travels up to
|
||||
C++ through a proxy class, and then back into PHP via a director method.
|
||||
If an exception occurs in PHP at this point, it would be nice for that
|
||||
exception to find its way back to the original caller. This can be done
|
||||
by combining a normal %exception directive with the
|
||||
<tt>director:except</tt> handler shown above. Here is an example of a
|
||||
suitable exception handler:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%exception {
|
||||
try { $action }
|
||||
catch (Swig::DirectorException &e) { SWIG_fail; }
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The class Swig::DirectorException used in this example is actually a
|
||||
base class of Swig::DirectorMethodException, so it will trap this
|
||||
exception. Because the PHP error state is still set when
|
||||
Swig::DirectorMethodException is thrown, PHP will register the exception
|
||||
as soon as the C wrapper function returns.
|
||||
</p>
|
||||
|
||||
<H3><a name="Php_nn3_5"></a>29.3.5 Overhead and code bloat</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Enabling directors for a class will generate a new director method for
|
||||
every virtual method in the class' inheritance chain. This alone can
|
||||
generate a lot of code bloat for large hierarchies. Method arguments
|
||||
that require complex conversions to and from target language types can
|
||||
result in large director methods. For this reason it is recommended that
|
||||
you selectively enable directors only for specific classes that are
|
||||
likely to be extended in PHP and used in C++.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Compared to classes that do not use directors, the call routing in the
|
||||
director methods does add some overhead. In particular, at least one
|
||||
dynamic cast and one extra function call occurs per method call from
|
||||
PHP. Relative to the speed of PHP execution this is probably completely
|
||||
negligible. For worst case routing, a method call that ultimately
|
||||
resolves in C++ may take one extra detour through PHP in order to ensure
|
||||
that the method does not have an extended PHP implementation. This could
|
||||
result in a noticeable overhead in some cases.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Although directors make it natural to mix native C++ objects with PHP
|
||||
objects (as director objects) via a common base class pointer, one
|
||||
should be aware of the obvious fact that method calls to PHP objects
|
||||
will be much slower than calls to C++ objects. This situation can be
|
||||
optimized by selectively enabling director methods (using the %feature
|
||||
directive) for only those methods that are likely to be extended in PHP.
|
||||
</p>
|
||||
|
||||
<H3><a name="Php_nn3_6"></a>29.3.6 Typemaps</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Typemaps for input and output of most of the basic types from director
|
||||
classes have been written. These are roughly the reverse of the usual
|
||||
input and output typemaps used by the wrapper code. The typemap
|
||||
operation names are 'directorin', 'directorout', and 'directorargout'.
|
||||
The director code does not currently use any of the other kinds of
|
||||
typemaps. It is not clear at this point which kinds are appropriate and
|
||||
need to be supported.
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="Php_nn3_7"></a>29.3.7 Miscellaneous</H3>
|
||||
|
||||
|
||||
<p> Director typemaps for STL classes are mostly in place, and hence you
|
||||
should be able to use std::string, etc., as you would any other type.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -102,8 +102,6 @@ by SWIG when it is parsing the interface:
|
|||
<div class="code"><pre>
|
||||
SWIG Always defined when SWIG is processing a file
|
||||
SWIGIMPORTED Defined when SWIG is importing a file with <tt>%import</tt>
|
||||
SWIGMAC Defined when running SWIG on the Macintosh
|
||||
SWIGWIN Defined when running SWIG under Windows
|
||||
SWIG_VERSION Hexadecimal number containing SWIG version,
|
||||
such as 0x010311 (corresponding to SWIG-1.3.11).
|
||||
|
||||
|
|
|
|||
|
|
@ -69,9 +69,6 @@
|
|||
<li><a href="#Python_nn47">Simple pointers</a>
|
||||
<li><a href="#Python_nn48">Unbounded C Arrays</a>
|
||||
<li><a href="#Python_nn49">String handling</a>
|
||||
<li><a href="#Python_nn50">Arrays</a>
|
||||
<li><a href="#Python_nn51">String arrays</a>
|
||||
<li><a href="#Python_nn52">STL wrappers</a>
|
||||
</ul>
|
||||
<li><a href="#Python_nn53">Typemaps</a>
|
||||
<ul>
|
||||
|
|
@ -339,7 +336,7 @@ python that you run the command with. Taking apart the command line:
|
|||
setup.py is the tradition)
|
||||
<li> <tt>build_ext</tt> -- telling distutils to build extensions
|
||||
<li> <tt>--inplace</tt> -- this tells distutils to put the extension lib in the current dir.
|
||||
Other wise, it will put it inside a build hierarchy, and you'd have to move it to use it.
|
||||
Otherwise, it will put it inside a build hierarchy, and you'd have to move it to use it.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
|
@ -363,8 +360,8 @@ program using commands like this (shown for Linux):
|
|||
|
||||
<div class="shell"><pre>
|
||||
$ swig -python example.i
|
||||
$ gcc -c -fPIC example.c
|
||||
$ gcc -c -fPIC example_wrap.c -I/usr/local/include/python2.0
|
||||
$ gcc -O2 -fPIC -c example.c
|
||||
$ gcc -O2 -fPIC -c example_wrap.c -I/usr/local/include/python2.5
|
||||
$ gcc -shared example.o example_wrap.o -o _example.so
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -433,7 +430,7 @@ extern int mod(int, int);
|
|||
extern double My_variable;
|
||||
%}
|
||||
|
||||
%include embed.i // Include code for a static version of Python
|
||||
%include "embed.i" // Include code for a static version of Python
|
||||
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -654,26 +651,19 @@ compiler. For example:
|
|||
|
||||
<div class="shell"><pre>
|
||||
$ swig -c++ -python example.i
|
||||
$ g++ -c example.cxx
|
||||
$ g++ -c example_wrap.cxx -I/usr/local/include/python2.0
|
||||
$ g++ -O2 -fPIC -c example.cxx
|
||||
$ g++ -O2 -fPIC -c example_wrap.cxx -I/usr/local/include/python2.5
|
||||
$ g++ -shared example.o example_wrap.o -o _example.so
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
On some platforms, you could also need to generate
|
||||
position-independent code (PIC), by using a compiler option such as -fPIC.
|
||||
Notably, the x86_64 (Opteron and EM64T) platform requires it, and when
|
||||
using the GNU Compiler Suite, you will need to modify the previous example
|
||||
as follows:
|
||||
The -fPIC option tells GCC to generate position-independent code (PIC)
|
||||
which is required for most architectures (it's not vital on x86, but
|
||||
still a good idea as it allows code pages from the library to be shared between
|
||||
processes). Other compilers may need a different option specified instead of
|
||||
-fPIC.
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
$ swig -c++ -python example.i
|
||||
$ g++ -fPIC -c example.cxx
|
||||
$ g++ -fPIC -c example_wrap.cxx -I/usr/local/include/python2.0
|
||||
$ g++ -shared example.o example_wrap.o -o _example.so
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
In addition to this, you may need to include additional library
|
||||
files to make it work. For example, if you are using the Sun C++ compiler on
|
||||
|
|
@ -683,7 +673,7 @@ Solaris, you often need to add an extra library <tt>-lCrun</tt> like this:
|
|||
<div class="shell"><pre>
|
||||
$ swig -c++ -python example.i
|
||||
$ CC -c example.cxx
|
||||
$ CC -c example_wrap.cxx -I/usr/local/include/python2.0
|
||||
$ CC -c example_wrap.cxx -I/usr/local/include/python2.5
|
||||
$ CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o _example.so -lCrun
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1144,7 +1134,7 @@ simply represented as opaque values using an especial python container object:
|
|||
|
||||
<div class="targetlang"><pre>
|
||||
>>> print f
|
||||
<Swig Object at _08a71808_p_FILE>
|
||||
<Swig Object of type 'FILE *' at 0xb7d6f470>
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
|
|
@ -1154,7 +1144,7 @@ dereference the pointer from Python. Of course, that isn't much of a concern in
|
|||
</p>
|
||||
|
||||
<p>
|
||||
In older versions of Swig (1.3.22 or older), pointers were represented
|
||||
In older versions of SWIG (1.3.22 or older), pointers were represented
|
||||
using a plain string object. If you have an old package that still
|
||||
requires that representation, or you just feel nostalgic, you can
|
||||
always retrieve it by casting the pointer object to a string:
|
||||
|
|
@ -1178,7 +1168,7 @@ integer:
|
|||
|
||||
<p>
|
||||
However, the inverse operation is not possible, i.e., you can't build
|
||||
a Swig pointer object from a raw integer value.
|
||||
a SWIG pointer object from a raw integer value.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -1720,8 +1710,8 @@ If declarations such as these appear, you will get a warning message like this:
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int)
|
||||
at example.i:11.
|
||||
example.i:12: Warning 509: Overloaded method spam(short) effectively ignored,
|
||||
example.i:11: Warning 509: as it is shadowed by spam(int).
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -3861,15 +3851,6 @@ If you need to return binary data, you might use the
|
|||
also be used to extra binary data from arbitrary pointers.
|
||||
</p>
|
||||
|
||||
<H3><a name="Python_nn50"></a>31.7.5 Arrays</H3>
|
||||
|
||||
|
||||
<H3><a name="Python_nn51"></a>31.7.6 String arrays</H3>
|
||||
|
||||
|
||||
<H3><a name="Python_nn52"></a>31.7.7 STL wrappers</H3>
|
||||
|
||||
|
||||
<H2><a name="Python_nn53"></a>31.8 Typemaps</H2>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1559,7 +1559,7 @@ you'll see a warning message like: </p>
|
|||
|
||||
|
||||
<div class="code shell">
|
||||
<pre>example.i:5: Warning(802): Warning for Derived: Base Base2 ignored.<br>Multiple inheritance is not supported in Ruby.<br></pre>
|
||||
<pre>example.i:5: Warning 802: Warning for Derived: Base Base2 ignored.<br>Multiple inheritance is not supported in Ruby.<br></pre>
|
||||
|
||||
|
||||
|
||||
|
|
@ -1810,7 +1810,11 @@ message like this: </p>
|
|||
|
||||
|
||||
<div class="code shell">
|
||||
<pre>example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int)<br>at example.i:11.<br> </pre>
|
||||
<pre>
|
||||
example.i:12: Warning 509: Overloaded method spam(short) effectively ignored,
|
||||
example.i:11: Warning 509: as it is shadowed by spam(int).
|
||||
<br>
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
|
|
@ -2393,7 +2397,7 @@ intset;<br>
|
|||
|
||||
|
||||
|
||||
%include std_set.i<br>
|
||||
%include <std_set.i><br>
|
||||
|
||||
|
||||
|
||||
|
|
@ -7097,7 +7101,7 @@ being created. </div>
|
|||
with Ruby objects. The following functions may prove to be useful.
|
||||
(These functions plus many more can be found in <a href="http://www.rubycentral.com/book"><em>Programming
|
||||
Ruby</em></a>, by David Thomas and Andrew Hunt.) </p>
|
||||
<p>In addition, we list equivalent functions that Swig defines, which
|
||||
<p>In addition, we list equivalent functions that SWIG defines, which
|
||||
provide a language neutral conversion (these functions are defined for
|
||||
each swig language supported). If you are trying to create a swig
|
||||
file that will work under multiple languages, it is recommended you
|
||||
|
|
@ -7123,7 +7127,7 @@ across multiple languages.</p>
|
|||
<tbody>
|
||||
<tr>
|
||||
<th style="font-weight: bold;">RUBY</th>
|
||||
<th style="font-weight: bold;">Swig</th>
|
||||
<th style="font-weight: bold;">SWIG</th>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
|||
|
|
@ -174,13 +174,8 @@ int bar(int x);
|
|||
...
|
||||
</pre></div>
|
||||
<p>
|
||||
The name of the module is supplied using the special <tt>%module</tt>
|
||||
directive (or the <tt>-module</tt> command line option). This
|
||||
directive must appear at the beginning of the file and is used to name
|
||||
the resulting extension module (in addition, this name often defines
|
||||
a namespace in the target language). If the module name is supplied on the
|
||||
command line, it overrides the name specified with the
|
||||
<tt>%module</tt> directive.
|
||||
The module name is supplied using the special <tt>%module</tt>
|
||||
directive. Modules are described further in the <a href="Modules.html#Modules_introduction">Modules Introduction</a> section.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -335,10 +330,13 @@ currently supported:
|
|||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Non-conventional type declarations.
|
||||
<li>
|
||||
<p>
|
||||
Non-conventional type declarations.
|
||||
For example, SWIG does not support declarations such as the following
|
||||
(even though this is legal C):
|
||||
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
/* Non-conventional placement of storage specifier (extern) */
|
||||
|
|
@ -360,15 +358,19 @@ if you're feeling particularly obfuscated, you can certainly break SWIG (althoug
|
|||
</p>
|
||||
</li>
|
||||
|
||||
<li>Running SWIG on C++ source files (what would appear in a .C or .cxx file)
|
||||
is not recommended. Even though SWIG can parse C++ class declarations,
|
||||
it ignores declarations that are decoupled from their
|
||||
original class definition (the declarations are parsed, but a lot of warning
|
||||
messages may be generated). For example:
|
||||
<li>
|
||||
<p>
|
||||
Running SWIG on C++ source files (the code in a .C, .cpp or .cxx file) is not recommended.
|
||||
The usual approach is to feed SWIG header files for parsing C++ definitions and declarations.
|
||||
The main reason is if SWIG parses a scoped definition or declaration (as is normal for C++ source files),
|
||||
it is ignored, unless a declaration for the symbol was parsed earlier.
|
||||
For example
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
/* Not supported by SWIG */
|
||||
/* bar not wrapped unless foo has been defined and
|
||||
the declaration of bar within foo has already been parsed */
|
||||
int foo::bar(int) {
|
||||
... whatever ...
|
||||
}
|
||||
|
|
@ -376,9 +378,12 @@ int foo::bar(int) {
|
|||
</div>
|
||||
</li>
|
||||
|
||||
<li>Certain advanced features of C++ such as nested classes
|
||||
are not yet supported. Please see the section on using SWIG
|
||||
with C++ for more information.
|
||||
<li>
|
||||
<p>
|
||||
Certain advanced features of C++ such as nested classes
|
||||
are not yet fully supported. Please see the C++ <a href="SWIGPlus.html#SWIGPlus_nested_classes">Nested classes</a> section
|
||||
for more information.
|
||||
</p>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
|
@ -672,7 +677,6 @@ enum boolean {NO=0, YES=1};
|
|||
enum months {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG,
|
||||
SEP, OCT, NOV, DEC};
|
||||
%constant double BLAH = 42.37;
|
||||
#define F_CONST (double) 5 // A floating pointer constant with cast
|
||||
#define PI_4 PI/4
|
||||
#define FLAGS 0x04 | 0x08 | 0x40
|
||||
|
||||
|
|
@ -711,8 +715,15 @@ the declaration
|
|||
<p>
|
||||
defines a constant because <tt>PI</tt> was already defined as a
|
||||
constant and the value is known.
|
||||
However, for the same conservative reasons even a constant with a simple cast will be ignored, such as
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
#define F_CONST (double) 5 // A floating pointer constant with cast
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The use of constant expressions is allowed, but SWIG does not evaluate
|
||||
them. Rather, it passes them through to the output file and lets the C
|
||||
|
|
@ -786,6 +797,12 @@ In this case, the pointer <tt>e</tt> can change---it's only the value
|
|||
being pointed to that is read-only.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Please note that for const parameters or return types used in a function, SWIG pretty much ignores
|
||||
the fact that these are const, see the section on <a href="SWIGPlus.html#SWIGPlus_const">const-correctness</a>
|
||||
for more information.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Compatibility Note:</b> One reason for changing SWIG to handle
|
||||
<tt>const</tt> declarations as read-only variables is that there are
|
||||
|
|
@ -2361,7 +2378,7 @@ You can make a <tt>Vector</tt> look a lot like a class by writing a SWIG interfa
|
|||
#include "vector.h"
|
||||
%}
|
||||
|
||||
%include vector.h // Just grab original C header file
|
||||
%include "vector.h" // Just grab original C header file
|
||||
%extend Vector { // Attach these functions to struct Vector
|
||||
Vector(double x, double y, double z) {
|
||||
Vector *v;
|
||||
|
|
@ -2387,6 +2404,10 @@ You can make a <tt>Vector</tt> look a lot like a class by writing a SWIG interfa
|
|||
<p>
|
||||
Note the usage of the <tt>$self</tt> special variable.
|
||||
Its usage is identical to a C++ 'this' pointer and should be used whenever access to the struct instance is required.
|
||||
Also note that C++ constructor and destructor syntax has been used to simulate a constructor and destructor, even for C code.
|
||||
There is one subtle difference to a normal C++ constructor implementation though and that is although the constructor declaration
|
||||
is as per a normal C++ constructor, the newly constructed object must be returned <b>as if</b> the constructor declaration
|
||||
had a return value, a <tt>Vector *</tt> in this case.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -2484,7 +2505,7 @@ instead of a method. To do this, you might write some code like this:
|
|||
// Now supply the implementation of the Vector_magnitude_get function
|
||||
%{
|
||||
const double Vector_magnitude_get(Vector *v) {
|
||||
return (const double) return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
|
||||
return (const double) sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
|
||||
}
|
||||
%}
|
||||
|
||||
|
|
@ -2497,41 +2518,53 @@ of the object.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
A similar technique can also be used to work with problematic data members.
|
||||
A similar technique can also be used to work with data members that you want to process.
|
||||
For example, consider this interface:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
struct Person {
|
||||
char name[50];
|
||||
...
|
||||
}
|
||||
typedef struct {
|
||||
char name[50];
|
||||
...
|
||||
} Person;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
By default, the <tt>name</tt> attribute is read-only because SWIG does not
|
||||
normally know how to modify arrays. However, you can rewrite the interface
|
||||
as follows to change this:
|
||||
Say you wanted to ensure <tt>name</tt> was always upper case, you can rewrite
|
||||
the interface as follows to ensure this occurs whenever a name is read or written to:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
struct Person {
|
||||
%extend {
|
||||
char *name;
|
||||
}
|
||||
...
|
||||
typedef struct {
|
||||
%extend {
|
||||
char name[50];
|
||||
}
|
||||
...
|
||||
} Person;
|
||||
|
||||
%{
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
void make_upper(char *name) {
|
||||
char *c;
|
||||
for (c = name; *c; ++c)
|
||||
*c = (char)toupper((int)*c);
|
||||
}
|
||||
|
||||
// Specific implementation of set/get functions
|
||||
%{
|
||||
/* Specific implementation of set/get functions forcing capitalization */
|
||||
|
||||
char *Person_name_get(Person *p) {
|
||||
return p->name;
|
||||
make_upper(p->name);
|
||||
return p->name;
|
||||
}
|
||||
|
||||
void Person_name_set(Person *p, char *val) {
|
||||
strncpy(p->name,val,50);
|
||||
strncpy(p->name,val,50);
|
||||
make_upper(p->name);
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
|
|
@ -2541,7 +2574,7 @@ void Person_name_set(Person *p, char *val) {
|
|||
Finally, it should be stressed that even though <tt>%extend</tt>
|
||||
can be used to add new data members, these new members can not require
|
||||
the allocation of additional storage in the object (e.g., their values must
|
||||
be entirely synthesized from existing attributes of the structure).
|
||||
be entirely synthesized from existing attributes of the structure or obtained elsewhere).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -2624,10 +2657,16 @@ $o->{intRep}->{ivalue} = 7 # Change value of o.intRep.ivalue
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
If you have a lot nested structure declarations, it is
|
||||
If you have a lot of nested structure declarations, it is
|
||||
advisable to double-check them after running SWIG. Although,
|
||||
there is a good chance that they will work, you may have to
|
||||
modify the interface file in certain cases.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Finally, note that nesting is handled differently in C++ mode,
|
||||
see <a href="SWIGPlus.html#SWIGPlus_nested_classes">Nested classes</a>.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIG_nn39"></a>5.5.8 Other things to note about structure wrapping</H3>
|
||||
|
||||
|
|
@ -2711,6 +2750,10 @@ initialization code (in that order).
|
|||
</p>
|
||||
|
||||
<ul>
|
||||
<li><b>Begin section</b>. <br>
|
||||
A placeholder to put code at the beginning of the C/C++ wrapper file.
|
||||
</li>
|
||||
|
||||
<li><b>Runtime code</b>. <br>
|
||||
This code is internal to SWIG and is used to include
|
||||
type-checking and other support functions that are used by the rest of the module.
|
||||
|
|
@ -2883,10 +2926,16 @@ interface to your program.
|
|||
SWIG's <tt>%include</tt> directive to process an entire C
|
||||
source/header file.
|
||||
|
||||
<li>Make sure everything in the interface file uses ANSI C/C++syntax.
|
||||
<li>Make sure everything in the interface file uses ANSI C/C++ syntax.
|
||||
|
||||
<li>Make sure all necessary `<tt>typedef</tt>' declarations and
|
||||
type-information is available in the interface file.
|
||||
type-information is available in the interface file.
|
||||
In particular, ensure that the type information is specified in the correct order as required by a C/C++ compiler.
|
||||
Most importantly, define a type before it is used! A C compiler will tell you
|
||||
if the full type information is not available if it is needed, whereas
|
||||
SWIG will usually not warn or error out as it is designed to work without
|
||||
full type information. However, if type information is not specified
|
||||
correctly, the wrappers can be sub-optimal and even result in uncompileable C/C++ code.
|
||||
|
||||
<li>If your program has a main() function, you may need to rename it
|
||||
(read on).
|
||||
|
|
@ -2945,16 +2994,21 @@ extern void dump(FILE *f);
|
|||
|
||||
<p>
|
||||
Of course, in this case, our header file is pretty simple so we could
|
||||
have made an interface file like this as well:</p>
|
||||
use a simpler approach and use an interface file like this:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
/* File : interface.i */
|
||||
%module mymodule
|
||||
%include header.h
|
||||
%{
|
||||
#include "header.h"
|
||||
%}
|
||||
%include "header.h"
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Naturally, your mileage may vary.</p>
|
||||
The main advantage of this approach is minimal maintenance of an interface file for when the header file changes in the future.
|
||||
In more complex projects, an interface file containing numerous <tt>%include</tt> and <tt>#include</tt> statements like this is one of the most common approaches to interface file design due to lower maintenance overhead.
|
||||
</p>
|
||||
|
||||
<H3><a name="SWIG_nn48"></a>5.7.3 Why use separate interface files?</H3>
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
<li><a href="#SWIGPlus_nn34">Smart pointers and operator->()</a>
|
||||
<li><a href="#SWIGPlus_nn35">Using declarations and inheritance</a>
|
||||
<li><a href="#SWIGPlus_nested_classes">Nested classes</a>
|
||||
<li><a href="#SWIGPlus_nn37">A brief rant about const-correctness</a>
|
||||
<li><a href="#SWIGPlus_const">A brief rant about const-correctness</a>
|
||||
<li><a href="#SWIGPlus_nn42">Where to go for more information</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -1616,7 +1616,7 @@ warning message like this:
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:18: Warning(401): Nothing known about base class 'Foo'. Ignored.
|
||||
example.i:18: Warning 401: Nothing known about base class 'Foo'. Ignored.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2031,7 +2031,8 @@ Therefore, when SWIG encounters this situation, it may generate a warning messag
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:4: Warning(509): Overloaded foo(long) is shadowed by foo(int) at example.i:3.
|
||||
example.i:4: Warning 509: Overloaded method foo(long) effectively ignored,
|
||||
example.i:3: Warning 509: as it is shadowed by foo(int).
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2041,7 +2042,8 @@ or for statically typed languages like Java:
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:4: Warning(516): Overloaded method foo(long) ignored. Method foo(int)
|
||||
example.i:4: Warning 516: Overloaded method foo(long) ignored,
|
||||
example.i:3: Warning 516: using foo(int) instead.
|
||||
at example.i:3 used.
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -2091,7 +2093,7 @@ When wrapping an overloaded function, there is a chance that you will get an err
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:3: Warning(467): Overloaded foo(int) not supported (no type checking
|
||||
example.i:3: Warning 467: Overloaded foo(int) not supported (no type checking
|
||||
rule for 'int').
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -3246,22 +3248,39 @@ public:
|
|||
</div>
|
||||
|
||||
<p>
|
||||
SWIG should be able to handle most simple uses of partial specialization. However, it may fail
|
||||
to match templates properly in more complicated cases. For example, if you have this code,
|
||||
SWIG supports both template explicit specialization and partial specialization. Consider:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
template<class T1, class T2> class Foo<T1, T2 *> { };
|
||||
template<class T1, class T2> class Foo { }; // (1) primary template
|
||||
template<> class Foo<double *, int *> { }; // (2) explicit specialization
|
||||
template<class T1, class T2> class Foo<T1, T2 *> { }; // (3) partial specialization
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
SWIG isn't able to match it properly for instantiations like <tt>Foo<int *, int *></tt>.
|
||||
This problem is not due to parsing, but due to the fact that SWIG does not currently implement all
|
||||
of the C++ argument deduction rules.
|
||||
SWIG is able to properly match explicit instantiations:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
<tt>Foo<double *, int *></tt> // explicit specialization matching (2)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
SWIG implements template argument deduction so that the following partial specialization examples work just like they would with a C++ compiler:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
<tt>Foo<int *, int *></tt> // partial specialization matching (3)
|
||||
<tt>Foo<int *, const int *></tt> // partial specialization matching (3)
|
||||
<tt>Foo<int *, int **></tt> // partial specialization matching (3)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Member function templates are supported. The underlying principle is the same
|
||||
as for normal templates--SWIG can't create a wrapper unless you provide
|
||||
|
|
@ -3471,7 +3490,7 @@ instead:
|
|||
|
||||
<p>
|
||||
In this case, the default and conversion constructors have the same
|
||||
name. Hence, Swig will overload them and define an unique visible
|
||||
name. Hence, SWIG will overload them and define an unique visible
|
||||
constructor, that will dispatch the proper call depending on the argument
|
||||
type.
|
||||
</p>
|
||||
|
|
@ -3817,7 +3836,7 @@ When this conflict occurs, you will get an error message that resembles this:
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:26. Error. 'foo' is multiply defined in the generated module.
|
||||
example.i:26. Error. 'foo' is multiply defined in the generated target language module.
|
||||
example.i:23. Previous declaration of 'foo'
|
||||
</pre>
|
||||
</div>
|
||||
|
|
@ -4678,37 +4697,50 @@ public:
|
|||
|
||||
|
||||
<p>
|
||||
There is limited support for nested structs and unions when wrapping C code, see <a href="SWIG.html#SWIG_nested_structs">Nested structures</a> for further details.
|
||||
However, there is no nested class/struct/union support when wrapping C++ code (using the -c++ commandline option).
|
||||
This may be added at a future date, however, until then some of the following workarounds can be applied.
|
||||
There is some support for nested structs and unions when wrapping C code,
|
||||
see <a href="SWIG.html#SWIG_nested_structs">Nested structures</a> for further details.
|
||||
The added complexity of C++ compared to C means this approach does not work well for
|
||||
C++ code (when using the -c++ command line option).
|
||||
For C++, a nested class is treated much like an opaque pointer, so anything useful within the nested class, such as its
|
||||
methods and variables, are not accessible from the target language.
|
||||
True nested class support may be added to SWIG in the future, however,
|
||||
until then some of the following workarounds can be applied to improve the situation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It might be possible to use partial class information. Since
|
||||
SWIG does not need the entire class specification to work, conditional
|
||||
compilation can be used to comment out the problematic nested class definition, you might do this:
|
||||
It might be possible to use partial class information as often you can accept that the nested class is not needed,
|
||||
especially if it is not actually used in any methods you need from the target language.
|
||||
Imagine you are wrapping the following <tt>Outer</tt> class which contains a nested class <tt>Inner</tt>.
|
||||
The easiest thing to do is turn a blind eye to the warning that SWIG generates, or simply suppress it:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
class Foo {
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
|
||||
|
||||
class Outer {
|
||||
public:
|
||||
#ifndef SWIG
|
||||
class Bar {
|
||||
public:
|
||||
...
|
||||
};
|
||||
#endif
|
||||
Foo();
|
||||
~Foo();
|
||||
...
|
||||
class Inner {
|
||||
public:
|
||||
...
|
||||
};
|
||||
Inner getInner();
|
||||
void useInner(const Inner& inner);
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The next workaround assumes you cannot modify the source code as was done above and it provides a solution for methods that use nested class types.
|
||||
Imagine we are wrapping the <tt>Outer</tt> class which contains a nested class <tt>Inner</tt>:
|
||||
Note that if <tt>Inner</tt> can be used as an opaque type, the default wrapping approach suffices.
|
||||
For example, if the nested class does not need to be created from the target language, but can be obtained via a method
|
||||
call, such as the <tt>getInner()</tt> method above, the returned value can then be passed around, such as passed into the
|
||||
<tt>useInner()</tt> method.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
With some more effort the above situation can be improved somewhat and a nested class can be constructed and used
|
||||
from the target language much like any other non-nested class. Assuming we have the <tt>Outer</tt> class in a header file:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -4721,14 +4753,18 @@ public:
|
|||
int var;
|
||||
Inner(int v = 0) : var(v) {}
|
||||
};
|
||||
void method(Inner inner);
|
||||
Inner getInner();
|
||||
void useInner(const Inner& inner);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The following interface file works around SWIG nested class limitations by redefining the nested class as a global class.
|
||||
A typedef for the compiler is also required in order for the generated wrappers to compile.
|
||||
The following interface file works around the nested class limitations by redefining the nested class as a global class.
|
||||
A typedef for the compiler and the <tt>nestedworkaround</tt>
|
||||
<a href="Customization.html#Customization_feature_flags">feature flag</a> is also required in
|
||||
order for the generated wrappers to compile. This flag simply removes all the type information from SWIG, so SWIG treats
|
||||
the nested class as if it had not been parsed at all.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
|
|
@ -4736,9 +4772,6 @@ A typedef for the compiler is also required in order for the generated wrappers
|
|||
// File : example.i
|
||||
%module example
|
||||
|
||||
// Suppress SWIG warning
|
||||
#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
|
||||
|
||||
// Redefine nested class in global scope in order for SWIG to generate
|
||||
// a proxy class. Only SWIG parses this definition.
|
||||
class Inner {
|
||||
|
|
@ -4747,25 +4780,64 @@ class Inner {
|
|||
Inner(int v = 0) : var(v) {}
|
||||
};
|
||||
|
||||
%nestedworkaround Outer::Inner;
|
||||
|
||||
%{
|
||||
#include "outer.h"
|
||||
%}
|
||||
%include "outer.h"
|
||||
|
||||
// We've fooled SWIG into thinking that Inner is a global class, so now we need
|
||||
// to trick the C++ compiler into understanding this apparent global type.
|
||||
%{
|
||||
// SWIG thinks that Inner is a global class, so we need to trick the C++
|
||||
// compiler into understanding this so called global type.
|
||||
typedef Outer::Inner Inner;
|
||||
%}
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The downside to this approach is having to maintain two definitions of <tt>Inner</tt>, the real one and the one in the interface file that SWIG parses.
|
||||
The downside to this approach is a more complex interface file and having to maintain two definitions of <tt>Inner</tt>,
|
||||
the real one and the one in the interface file that SWIG parses.
|
||||
However, the upside is that all the methods/variables in the nested class are available from the target language
|
||||
as a proxy class is generated instead of treating the nested class as an opaque type.
|
||||
The proxy class can be constructed from the target language and passed into any methods accepting the nested class.
|
||||
Also note that the original header file is parsed unmodified.
|
||||
</p>
|
||||
|
||||
<H2><a name="SWIGPlus_nn37"></a>6.27 A brief rant about const-correctness</H2>
|
||||
<p>
|
||||
Finally, conditional compilation can be used as a workaround to comment out nested class definitions in the actual headers,
|
||||
assuming you are able to modify them.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
// File outer.h
|
||||
class Outer {
|
||||
public:
|
||||
#ifndef SWIG
|
||||
class Inner {
|
||||
public:
|
||||
...
|
||||
};
|
||||
#endif
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This workaround used to be common when SWIG could not deal with nested classes particulary well.
|
||||
This should just be a last resort for unusual corner cases now as SWIG can parse nested classes and even handle nested template classes fairly well.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Compatibility Note:</b> SWIG-1.3.40 and earlier versions did not have the <tt>nestedworkaround</tt> feature
|
||||
and the generated code resulting from parsing nested classes did not always compile.
|
||||
Nested class warnings could also not be suppressed using %warnfilter.
|
||||
</p>
|
||||
|
||||
|
||||
<H2><a name="SWIGPlus_const"></a>6.27 A brief rant about const-correctness</H2>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@
|
|||
<ul>
|
||||
<li><a href="#Tcl_nn45">Proxy classes</a>
|
||||
</ul>
|
||||
<li><a href="#Tcl_nn46">Tcl/Tk Stubs</a>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
|
@ -190,7 +191,7 @@ extern int mod(int, int);
|
|||
extern double My_variable;
|
||||
%}
|
||||
|
||||
%include tclsh.i // Include code for rebuilding tclsh
|
||||
%include "tclsh.i" // Include code for rebuilding tclsh
|
||||
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -1501,8 +1502,8 @@ If declarations such as these appear, you will get a warning message like this:
|
|||
|
||||
<div class="code">
|
||||
<pre>
|
||||
example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int)
|
||||
at example.i:11.
|
||||
example.i:12: Warning 509: Overloaded method spam(short) effectively ignored,
|
||||
example.i:11: Warning 509: as it is shadowed by spam(int).
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -2822,7 +2823,7 @@ int print_args(char **argv) {
|
|||
return i;
|
||||
}
|
||||
%}
|
||||
%include tclsh.i
|
||||
%include "tclsh.i"
|
||||
|
||||
</pre></div>
|
||||
|
||||
|
|
@ -3409,5 +3410,27 @@ short, but clever Tcl script can be combined with SWIG to do many
|
|||
interesting things.
|
||||
</p>
|
||||
|
||||
<H2><a name="Tcl_nn46"></a>33.10 Tcl/Tk Stubs</H2>
|
||||
|
||||
|
||||
<p>
|
||||
For background information about the Tcl Stubs feature, see
|
||||
<a href="http://www.tcl.tk/doc/howto/stubs.html">http://www.tcl.tk/doc/howto/stubs.html</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As of SWIG 1.3.10, the generated C/C++ wrapper will use the Tcl Stubs
|
||||
feature if compiled with <tt>-DUSE_TCL_STUBS</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As of SWIG 1.3.40, the generated C/C++ wrapper will use the Tk Stubs
|
||||
feature if compiled with <tt>-DUSE_TK_STUBS</tt>. Also, you can override
|
||||
the minimum version to support which is passed to <tt>Tcl_InitStubs()</tt>
|
||||
and <tt>Tk_InitStubs()</tt> with <tt>-DSWIG_TCL_STUBS_VERSION="8.3"</tt>
|
||||
or the version being compiled with using
|
||||
<tt>-DSWIG_TCL_STUBS_VERSION=TCL_VERSION</tt>.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -22,25 +22,31 @@
|
|||
</ul>
|
||||
<li><a href="#Typemaps_nn10">Typemap specifications</a>
|
||||
<ul>
|
||||
<li><a href="#Typemaps_nn11">Defining a typemap</a>
|
||||
<li><a href="#Typemaps_defining">Defining a typemap</a>
|
||||
<li><a href="#Typemaps_nn12">Typemap scope</a>
|
||||
<li><a href="#Typemaps_nn13">Copying a typemap</a>
|
||||
<li><a href="#Typemaps_nn14">Deleting a typemap</a>
|
||||
<li><a href="#Typemaps_nn15">Placement of typemaps</a>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_nn16">Pattern matching rules</a>
|
||||
<li><a href="#Typemaps_pattern_matching">Pattern matching rules</a>
|
||||
<ul>
|
||||
<li><a href="#Typemaps_nn17">Basic matching rules</a>
|
||||
<li><a href="#Typemaps_nn18">Typedef reductions</a>
|
||||
<li><a href="#Typemaps_typedef_reductions">Typedef reductions</a>
|
||||
<li><a href="#Typemaps_nn19">Default typemaps</a>
|
||||
<li><a href="#Typemaps_mixed_default">Mixed default typemaps</a>
|
||||
<li><a href="#Typemaps_nn20">Multi-arguments typemaps</a>
|
||||
<li><a href="#Typemaps_debugging_search">Debugging typemap pattern matching</a>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_nn21">Code generation rules</a>
|
||||
<ul>
|
||||
<li><a href="#Typemaps_nn22">Scope</a>
|
||||
<li><a href="#Typemaps_nn23">Declaring new local variables</a>
|
||||
<li><a href="#Typemaps_special_variables">Special variables</a>
|
||||
<li><a href="#Typemaps_special_variable_macros">Special variable macros</a>
|
||||
<ul>
|
||||
<li><a href="#Typemaps_special_macro_descriptor">$descriptor(type)</a>
|
||||
<li><a href="#Typemaps_special_macro_typemap">$typemap(method, typepattern)</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_nn25">Common typemap methods</a>
|
||||
<ul>
|
||||
|
|
@ -63,13 +69,13 @@
|
|||
<li><a href="#Typemaps_nn40">Typemaps for arrays</a>
|
||||
<li><a href="#Typemaps_nn41">Implementing constraints with typemaps</a>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_nn43">Typemaps for multiple languages</a>
|
||||
<li><a href="#Typemaps_nn43">Typemaps for multiple target languages</a>
|
||||
<li><a href="#Typemaps_optimal">Optimal code generation when returning by value</a>
|
||||
<li><a href="#Typemaps_multi_argument_typemaps">Multi-argument typemaps</a>
|
||||
<li><a href="#runtime_type_checker">The run-time type checker</a>
|
||||
<ul>
|
||||
<li><a href="#Typemaps_nn45">Implementation</a>
|
||||
<li><a href="#Typemaps_nn46">Usage</a>
|
||||
<li><a href="#Typemaps_runtime_type_checker_usage">Usage</a>
|
||||
</ul>
|
||||
<li><a href="#Typemaps_overloading">Typemaps and overloading</a>
|
||||
<li><a href="#Typemaps_nn48">More about <tt>%apply</tt> and <tt>%clear</tt></a>
|
||||
|
|
@ -83,10 +89,6 @@
|
|||
|
||||
|
||||
|
||||
<p>
|
||||
<b>Disclaimer: This chapter is under construction!</b>
|
||||
</p>
|
||||
|
||||
<H2><a name="Typemaps_nn2"></a>10.1 Introduction</H2>
|
||||
|
||||
|
||||
|
|
@ -225,14 +227,17 @@ At first glance, this code will look a little confusing.
|
|||
However, there is really not much to it. The first typemap (the "in"
|
||||
typemap) is used to convert a value from the target language to C. The second
|
||||
typemap (the "out" typemap) is used to convert in the other
|
||||
direction. The content of each typemap is a small fragment of C code
|
||||
that is inserted directly into the SWIG generated wrapper functions. Within
|
||||
this code, a number of special variables prefixed with a $ are expanded. These are
|
||||
really just placeholders for C variables that are generated in the course
|
||||
direction. The content of each typemap is a small fragment of code
|
||||
that is inserted directly into the SWIG generated wrapper functions.
|
||||
The code is usually C or C++ code which will be generated into the C/C++ wrapper functions.
|
||||
Note that this isn't always the case as some target language modules allow target language
|
||||
code within the typemaps which gets generated into target language specific files.
|
||||
Within this code, a number of special variables prefixed with a $ are expanded. These are
|
||||
really just placeholders for C/C++ variables that are generated in the course
|
||||
of creating the wrapper function. In this case, <tt>$input</tt> refers to an
|
||||
input object that needs to be converted to C and <tt>$result</tt>
|
||||
input object that needs to be converted to C/C++ and <tt>$result</tt>
|
||||
refers to an object that is going to be returned by a wrapper
|
||||
function. <tt>$1</tt> refers to a C variable that has the same type as
|
||||
function. <tt>$1</tt> refers to a C/C++ variable that has the same type as
|
||||
specified in the typemap declaration (an <tt>int</tt> in this
|
||||
example).
|
||||
</p>
|
||||
|
|
@ -655,7 +660,7 @@ of "The C Programming Language" by Kernighan and Ritchie or
|
|||
This section describes the behavior of the <tt>%typemap</tt> directive itself.
|
||||
</p>
|
||||
|
||||
<H3><a name="Typemaps_nn11"></a>10.2.1 Defining a typemap</H3>
|
||||
<H3><a name="Typemaps_defining"></a>10.2.1 Defining a typemap</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -676,8 +681,9 @@ these methods is described later.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<em>modifiers</em> is an optional comma separated list of <tt>name="value"</tt> values. These
|
||||
are sometimes to attach extra information to a typemap and is often target-language dependent.
|
||||
<em>modifiers</em> is an optional comma separated list of <tt>name="value"</tt> values.
|
||||
These are sometimes to attach extra information to a typemap and is often target-language dependent.
|
||||
They are also known as typemap attributes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -988,11 +994,12 @@ It should be noted that for scoping to work, SWIG has to know that <tt>string</t
|
|||
within a particular namespace. In this example, this is done using the class declaration <tt>class string</tt>.
|
||||
</p>
|
||||
|
||||
<H2><a name="Typemaps_nn16"></a>10.3 Pattern matching rules</H2>
|
||||
<H2><a name="Typemaps_pattern_matching"></a>10.3 Pattern matching rules</H2>
|
||||
|
||||
|
||||
<p>
|
||||
The section describes the pattern matching rules by which C datatypes are associated with typemaps.
|
||||
The section describes the pattern matching rules by which C/C++ datatypes are associated with typemaps.
|
||||
The matching rules can be observed in practice by using the debugging options also described.
|
||||
</p>
|
||||
|
||||
<H3><a name="Typemaps_nn17"></a>10.3.1 Basic matching rules</H3>
|
||||
|
|
@ -1007,18 +1014,19 @@ is used.
|
|||
<ul>
|
||||
<li>Typemaps that exactly match <tt>TYPE</tt> and <tt>NAME</tt>.
|
||||
<li>Typemaps that exactly match <tt>TYPE</tt> only.
|
||||
<li>If <tt>TYPE</tt> is a C++ template of type <tt>T< TPARMS ></tt>, where <tt>TPARMS</tt> are the template parameters,
|
||||
the type is stripped of the template parameters and the following checks are then made:
|
||||
<ul>
|
||||
<li>Typemaps that exactly match <tt>T</tt> and <tt>NAME</tt>.
|
||||
<li>Typemaps that exactly match <tt>T</tt> only.
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
If <tt>TYPE</tt> includes qualifiers (const, volatile, etc.), they are stripped and the following
|
||||
checks are made:
|
||||
If <tt>TYPE</tt> includes qualifiers (const, volatile, etc.), they are stripped to form a new stripped type
|
||||
and the matching rules above are repeated on the stripped type.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Typemaps that match the stripped <tt>TYPE</tt> and <tt>NAME</tt>.
|
||||
<Li>Typemaps that match the stripped <tt>TYPE</tt> only.
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
If <tt>TYPE</tt> is an array. The following transformation is made:
|
||||
</p>
|
||||
|
|
@ -1086,7 +1094,7 @@ void F(int x[1000]); // int [ANY] rule (typemap 5)
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<H3><a name="Typemaps_nn18"></a>10.3.2 Typedef reductions</H3>
|
||||
<H3><a name="Typemaps_typedef_reductions"></a>10.3.2 Typedef reductions</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1241,6 +1249,26 @@ is rather esoteric--there's little practical reason to write a typemap quite lik
|
|||
to confuse your coworkers even more.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As a point of clarification, it is worth emphasizing that typedef matching is a typedef <b>reduction</b> process only, that is, SWIG does not search for every single possible typedef.
|
||||
Given a type in a declaration, it will only reduce the type, it won't build it up looking for typedefs.
|
||||
For example, given the type <tt>Struct</tt>, the typemap below will not be used for the <tt>aStruct</tt> parameter,
|
||||
because <tt>Struct</tt> is fully reduced:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
struct Struct {...};
|
||||
typedef Struct StructTypedef;
|
||||
|
||||
%typemap(in) StructTypedef {
|
||||
...
|
||||
}
|
||||
|
||||
void go(Struct aStruct);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H3><a name="Typemaps_nn19"></a>10.3.3 Default typemaps</H3>
|
||||
|
||||
|
||||
|
|
@ -1378,7 +1406,7 @@ Expect to see them being used more and more within the various libraries in late
|
|||
</p>
|
||||
|
||||
|
||||
<H3><a name="Typemaps_nn20"></a>10.3.5 Multi-arguments typemaps</H3>
|
||||
<H3><a name="Typemaps_multi_argument_typemaps"></a>10.3.5 Multi-arguments typemaps</H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1408,6 +1436,205 @@ but all subsequent arguments must match exactly.
|
|||
</p>
|
||||
|
||||
|
||||
<H3><a name="Typemaps_debugging_search"></a>10.3.6 Debugging typemap pattern matching</H3>
|
||||
|
||||
|
||||
<p>
|
||||
There are two useful debug command line options available for debugging typemaps, <tt>-debug-tmsearch</tt> and <tt>-debug-tmused</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <tt>-debug-tmsearch</tt> option is a verbose option for debugging typemap searches.
|
||||
This can be very useful for watching the pattern matching process in action and for debugging which typemaps are used.
|
||||
The option displays all the typemaps and types that are looked for until a successful pattern match is made.
|
||||
As the display includes searches for each and every type needed for wrapping, the amount of information displayed can be large.
|
||||
Normally you would manually search through the displayed information for the particular type that you are interested in.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, consider some of the code used in the <a href="#Typemaps_typedef_reductions">Typedef reductions</a> section already covered:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
typedef int Integer;
|
||||
typedef Integer Row4[4];
|
||||
void foo(Row4 rows[10]);
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
A sample of the debugging output is shown below for the "in" typemap:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
swig -perl -debug-tmsearch example.i
|
||||
...
|
||||
example.h:3: Searching for a suitable 'in' typemap for: Row4 rows[10]
|
||||
Looking for: Row4 rows[10]
|
||||
Looking for: Row4 [10]
|
||||
Looking for: Row4 rows[ANY]
|
||||
Looking for: Row4 [ANY]
|
||||
Looking for: Integer rows[10][4]
|
||||
Looking for: Integer [10][4]
|
||||
Looking for: Integer rows[ANY][ANY]
|
||||
Looking for: Integer [ANY][ANY]
|
||||
Looking for: int rows[10][4]
|
||||
Looking for: int [10][4]
|
||||
Looking for: int rows[ANY][ANY]
|
||||
Looking for: int [ANY][ANY]
|
||||
Looking for: SWIGTYPE rows[ANY][ANY]
|
||||
Looking for: SWIGTYPE [ANY][ANY]
|
||||
Looking for: SWIGTYPE rows[ANY][]
|
||||
Looking for: SWIGTYPE [ANY][]
|
||||
Looking for: SWIGTYPE *rows[ANY]
|
||||
Looking for: SWIGTYPE *[ANY]
|
||||
Looking for: SWIGTYPE rows[ANY]
|
||||
Looking for: SWIGTYPE [ANY]
|
||||
Looking for: SWIGTYPE rows[]
|
||||
Looking for: SWIGTYPE []
|
||||
Using: %typemap(in) SWIGTYPE []
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
showing that the best default match supplied by SWIG is the <tt>SWIGTYPE []</tt> typemap.
|
||||
As the example shows, the successful match displays just the typemap method name and type in this format: <tt>%typemap(method) type</tt>.
|
||||
This information might meet your debugging needs, however, you might want to analyze further.
|
||||
If you next invoke SWIG with the <tt>-E</tt> option to display the preprocessed output, and search for this particular typemap,
|
||||
you'll find the full typemap contents (example shown below for Python):
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(in, noblock=1) SWIGTYPE [] (void *argp = 0, int res = 0) {
|
||||
res = SWIG_ConvertPtr($input, &argp,$descriptor, $disown | 0 );
|
||||
if (!SWIG_IsOK(res)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'");
|
||||
}
|
||||
$1 = ($ltype)(argp);
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The generated code for the <tt>foo</tt> wrapper will then contain the snippets of the typemap with the special variables expanded.
|
||||
The rest of this chapter will need reading though to fully understand all of this, however, the relevant parts of the generated code for the above typemap can be seen below:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
SWIGINTERN PyObject *_wrap_foo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||
...
|
||||
void *argp1 = 0 ;
|
||||
int res1 = 0 ;
|
||||
...
|
||||
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_a_4__int, 0 | 0 );
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "foo" "', argument " "1"" of type '" "int [10][4]""'");
|
||||
}
|
||||
arg1 = (int (*)[4])(argp1);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Searches for multi-argument typemaps are not mentioned unless a matching multi-argument typemap does actually exist.
|
||||
For example, the output for the code in the <a href="#Typemaps_multi_argument_typemaps">previous section</a> is as follows:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
...
|
||||
example.h:39: Searching for a suitable 'in' typemap for: char *buffer
|
||||
Looking for: char *buffer
|
||||
Multi-argument typemap found...
|
||||
Using: %typemap(in) (char *buffer,int len)
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The second option for debugging is <tt>-debug-tmused</tt> and this displays the typemaps used.
|
||||
This option is a less verbose version of the <tt>-debug-tmsearch</tt> option as it only displays each successfully found typemap on a separate single line.
|
||||
The output displays the type, and name if present, the typemap method in brackets and then the actual typemap used.
|
||||
Below is the output for the example code at the start of this section on debugging.
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
$ swig -perl -debug-tmused example.i
|
||||
example.h:3: Typemap for Row4 rows[10] (in) : %typemap(in) SWIGTYPE []
|
||||
example.h:3: Typemap for Row4 rows[10] (typecheck) : %typemap(typecheck) SWIGTYPE *
|
||||
example.h:3: Typemap for Row4 rows[10] (freearg) : %typemap(freearg) SWIGTYPE []
|
||||
example.h:3: Typemap for void foo (out) : %typemap(out) void
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Now, consider the following interface file:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%module example
|
||||
|
||||
%{
|
||||
void set_value(const char* val) {}
|
||||
%}
|
||||
|
||||
%typemap(check) char *NON_NULL {
|
||||
if (!$1) {
|
||||
/* ... error handling ... */
|
||||
}
|
||||
}
|
||||
|
||||
%apply SWIGTYPE * { const char* val, const char* another_value } // use default pointer handling instead of strings
|
||||
|
||||
%typemap(check) const char* val = char* NON_NULL;
|
||||
|
||||
%typemap(arginit, noblock=1) const char* val {
|
||||
$1 = "";
|
||||
}
|
||||
|
||||
void set_value(const char* val);
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
and the output debug:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
swig -perl5 -debug-tmused example.i
|
||||
example.i:21: Typemap for char const *val (arginit) : %typemap(arginit) char const *val
|
||||
example.i:21: Typemap for char const *val (in) : %apply SWIGTYPE * { char const *val }
|
||||
example.i:21: Typemap for char const *val (typecheck) : %apply SWIGTYPE * { char const *val }
|
||||
example.i:21: Typemap for char const *val (check) : %typemap(check) char const *val = char *NON_NULL
|
||||
example.i:21: Typemap for char const *val (freearg) : %apply SWIGTYPE * { char const *val }
|
||||
example.i:21: Typemap for void set_value (out) : %typemap(out) void
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The following observations about what is displayed can be noted (the same applies for <tt>-debug-tmsearch</tt>):
|
||||
<li>
|
||||
The relevant typemap is shown, but for typemap copying, the appropriate <tt>%typemap</tt> or <tt>%apply</tt> is displayed, for example, the "check" and "in" typemaps.
|
||||
</li>
|
||||
<li>
|
||||
The typemap modifiers are not shown, eg the <tt>noblock=1</tt> modifier in the "arginit" typemap.
|
||||
</li>
|
||||
<li>
|
||||
The exact <tt>%apply</tt> statement might look different to what is in the actual code. For example, the <tt>const char* another_value</tt> is not shown as it is not relevant here.
|
||||
Also the types may be displayed slightly differently - <tt>char const *</tt> and not <tt>const char*</tt>.
|
||||
</li>
|
||||
</p>
|
||||
|
||||
<H2><a name="Typemaps_nn21"></a>10.4 Code generation rules</H2>
|
||||
|
||||
|
||||
|
|
@ -1646,6 +1873,7 @@ each type must have its own local variable declaration.
|
|||
|
||||
<p>
|
||||
Within all typemaps, the following special variables are expanded.
|
||||
This is by no means a complete list as some target languages have additional special variables which are documented in the language specific chapters.
|
||||
</p>
|
||||
|
||||
<center>
|
||||
|
|
@ -1892,6 +2120,86 @@ Another approach, which only works for arrays is to use the <tt>$1_basetype</tt>
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<H3><a name="Typemaps_special_variable_macros"></a>10.4.4 Special variable macros</H3>
|
||||
|
||||
|
||||
<p>
|
||||
Special variable macros are like macro functions in that they take one or more input arguments
|
||||
which are used for the macro expansion.
|
||||
They look like macro/function calls but use the special variable <tt>$</tt> prefix to the macro name.
|
||||
Note that unlike normal macros, the expansion is not done by the preprocessor,
|
||||
it is done during the SWIG parsing/compilation stages.
|
||||
The following special variable macros are available across all language modules.
|
||||
</p>
|
||||
|
||||
<H4><a name="Typemaps_special_macro_descriptor"></a>10.4.4.1 $descriptor(type)</H4>
|
||||
|
||||
|
||||
<p>
|
||||
This macro expands into the type descriptor structure for any C/C++ type specified in <tt>type</tt>.
|
||||
It behaves like the <tt>$1_descriptor</tt> special variable described above except that the type to expand is
|
||||
taken from the macro argument rather than inferred from the typemap type.
|
||||
For example, <tt>$descriptor(std::vector<int> *)</tt> will expand into <tt>SWIGTYPE_p_std__vectorT_int_t</tt>.
|
||||
This macro is mostly used in the scripting target languages and is demonstrated later in the <a href="#Typemaps_runtime_type_checker_usage">Run-time type checker usage</a> section.
|
||||
</p>
|
||||
|
||||
<H4><a name="Typemaps_special_macro_typemap"></a>10.4.4.2 $typemap(method, typepattern)</H4>
|
||||
|
||||
|
||||
<p>
|
||||
This macro uses the <a href="#Typemaps_pattern_matching">pattern matching rules</a> described earlier to lookup and
|
||||
then substitute the special variable macro with the code in the matched typemap.
|
||||
The typemap to search for is specified by the arguments, where <tt>method</tt> is the typemap method name and
|
||||
<tt>typepattern</tt> is a type pattern as per the <tt>%typemap</tt> specification in the <a href="#Typemaps_defining">Defining a typemap</a> section.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The special variables within the matched typemap are expanded into those for the matched typemap type,
|
||||
not the typemap within which the macro is called.
|
||||
In practice, there is little use for this macro in the scripting target languages.
|
||||
It is mostly used in the target languages that are statically typed as a way to obtain the target language type given the C/C++ type and more commonly only when the C++ type is a template parameter.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The example below is for C# only and uses some typemap method names documented in the C# chapter, but it shows some of the possible syntax variations.
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(cstype) unsigned long "uint"
|
||||
%typemap(cstype) unsigned long bb "bool"
|
||||
%typemap(cscode) BarClass %{
|
||||
void foo($typemap(cstype, unsigned long aa) var1,
|
||||
$typemap(cstype, unsigned long bb) var2,
|
||||
$typemap(cstype, (unsigned long bb)) var3,
|
||||
$typemap(cstype, unsigned long) var4)
|
||||
{
|
||||
// do something
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
The result is the following expansion
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%typemap(cstype) unsigned long "uint"
|
||||
%typemap(cstype) unsigned long bb "bool"
|
||||
%typemap(cscode) BarClass %{
|
||||
void foo(uint var1,
|
||||
bool var2,
|
||||
bool var3,
|
||||
uint var4)
|
||||
{
|
||||
// do something
|
||||
}
|
||||
%}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<H2><a name="Typemaps_nn25"></a>10.5 Common typemap methods</H2>
|
||||
|
||||
|
||||
|
|
@ -2600,12 +2908,12 @@ rather than blindly passing values to the underlying C/C++ program.</p>
|
|||
Note: A more advanced constraint checking system is in development. Stay tuned.
|
||||
</p>
|
||||
|
||||
<H2><a name="Typemaps_nn43"></a>10.7 Typemaps for multiple languages</H2>
|
||||
<H2><a name="Typemaps_nn43"></a>10.7 Typemaps for multiple target languages</H2>
|
||||
|
||||
|
||||
<p>
|
||||
The code within typemaps is usually language dependent,
|
||||
however, many languages support the same typemaps.
|
||||
however, many target languages support the same typemaps.
|
||||
In order to distinguish typemaps across different languages, the preprocessor should be used.
|
||||
For example, the "in" typemap for Perl and Ruby could be written as:
|
||||
</p>
|
||||
|
|
@ -2636,8 +2944,9 @@ The example above also shows a common approach of issuing a warning for an as ye
|
|||
<p>
|
||||
The "out" typemap is the main typemap for return types.
|
||||
This typemap supports an optional attribute flag called "optimal", which is for reducing
|
||||
temporary variables and the amount of generated code.
|
||||
It only really makes a difference when returning objects by value and it cannot always be used,
|
||||
temporary variables and the amount of generated code, thereby giving the compiler the opportunity to
|
||||
use <i>return value optimization</i> for generating faster executing code.
|
||||
It only really makes a difference when returning objects by value and has some limitations on usage,
|
||||
as explained later on.
|
||||
</p>
|
||||
|
||||
|
|
@ -2695,7 +3004,7 @@ XX(const XX &)
|
|||
Note that three objects are being created as well as an assignment.
|
||||
Wouldn't it be great if the <tt>XX::create()</tt> method was the only time a constructor was called?
|
||||
As the method returns by value, this is asking a lot and the code that SWIG generates by default
|
||||
makes it impossible for the compiler to make this type of optimisation.
|
||||
makes it impossible for the compiler to use <i>return value optimisation (RVO)</i>.
|
||||
However, this is where the "optimal" attribute in the "out" typemap can help out.
|
||||
If the typemap code is kept the same and just the "optimal" attribute specified like this:
|
||||
</p>
|
||||
|
|
@ -2754,7 +3063,7 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() {
|
|||
<p>
|
||||
The major difference is the <tt>result</tt> temporary variable holding the value returned from <tt>XX::create()</tt> is no longer generated and instead the copy constructor call is made directly from
|
||||
the value returned by <tt>XX::create()</tt>.
|
||||
With modern compiler optimisations turned on, the copy is not actually done, in fact the object is never created
|
||||
With modern compilers implementing RVO, the copy is not actually done, in fact the object is never created
|
||||
on the stack in <tt>XX::create()</tt> at all, it is simply created directly on the heap.
|
||||
In the first instance, the <tt>$1</tt> special variable in the typemap is expanded into <tt>result</tt>.
|
||||
In the second instance, <tt>$1</tt> is expanded into <tt>XX::create()</tt> and this is essentially
|
||||
|
|
@ -2762,7 +3071,7 @@ what the "optimal" attribute is telling SWIG to do.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
This kind of optimisation is not turned on by default as it has a number of restrictions.
|
||||
The "optimal" attribute optimisation is not turned on by default as it has a number of restrictions.
|
||||
Firstly, some code cannot be condensed into a simple call for passing into the copy constructor.
|
||||
One common occurrence is when <a href="Customization.html#exception">%exception</a> is used.
|
||||
Consider adding the following <tt>%exception</tt> to the example:
|
||||
|
|
@ -2786,8 +3095,8 @@ SWIG can detect when the "optimal" attribute cannot be used and will ignore it a
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
example.i:28: Warning(474): Method XX::create() usage of the optimal attribute in the out
|
||||
typemap at example.i:14 ignored as the following cannot be used to generate optimal code:
|
||||
example.i:28: Warning 474: Method XX::create() usage of the optimal attribute ignored
|
||||
example.i:14: Warning 474: in the out typemap as the following cannot be used to generate optimal code:
|
||||
try {
|
||||
result = XX::create();
|
||||
} catch(const std::exception &e) {
|
||||
|
|
@ -2808,8 +3117,8 @@ In fact SWIG attempts to detect this and will issue a warning something like:
|
|||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
example.i:21: Warning(475): Multiple calls to XX::create() might be generated due to
|
||||
optimal attribute usage in the out typemap at example.i:7.
|
||||
example.i:21: Warning 475: Multiple calls to XX::create() might be generated due to optimal attribute usage in
|
||||
example.i:7: Warning 475: the out typemap.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -3114,7 +3423,7 @@ language modules.</li>
|
|||
<p>
|
||||
The run-time type checker is used by many, but not all, of SWIG's supported target languages.
|
||||
The run-time type checker features
|
||||
are not required and are thus not used for strongly typed languages such as Java and C#.
|
||||
are not required and are thus not used for statically typed languages such as Java and C#.
|
||||
The scripting and scheme based languages rely on it and it forms
|
||||
a critical part of SWIG's operation for these languages.
|
||||
</p>
|
||||
|
|
@ -3294,7 +3603,7 @@ structures rather than creating new ones. These <tt>swig_module_info</tt>
|
|||
structures are chained together in a circularly linked list.
|
||||
</p>
|
||||
|
||||
<H3><a name="Typemaps_nn46"></a>10.10.2 Usage</H3>
|
||||
<H3><a name="Typemaps_runtime_type_checker_usage"></a>10.10.2 Usage</H3>
|
||||
|
||||
|
||||
<p>This section covers how to use these functions from typemaps. To learn how to
|
||||
|
|
@ -3334,8 +3643,8 @@ type tables and improves efficiency.
|
|||
|
||||
<p>
|
||||
Occasionally, you might need to write a typemap that needs to convert
|
||||
pointers of other types. To handle this, a special macro substitution
|
||||
<tt>$descriptor(type)</tt> can be used to generate the SWIG type
|
||||
pointers of other types. To handle this, the special variable macro
|
||||
<tt>$descriptor(type)</tt> covered earlier can be used to generate the SWIG type
|
||||
descriptor name for any C datatype. For example:
|
||||
</p>
|
||||
|
||||
|
|
@ -3973,6 +4282,7 @@ numerous examples. You should look at these files to get a feel
|
|||
for how to define typemaps of your own.
|
||||
Some of the language modules support additional typemaps and further
|
||||
information is available in the individual chapters for each target language.
|
||||
There you may also find more hands-on practical examples.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -270,21 +270,37 @@ traceprintf(arg1, NULL);
|
|||
|
||||
<p>
|
||||
Arguably, this approach seems to defeat the whole point of variable length arguments. However,
|
||||
this actually provides enough support for many simple kinds of varargs functions to still be useful. For
|
||||
instance, you could make function calls like this (in Python):
|
||||
this actually provides enough support for many simple kinds of varargs functions to still be useful, however it does come with a caveat.
|
||||
For instance, you could make function calls like this (in Python):
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> traceprintf("Hello World")
|
||||
>>> traceprintf("Hello %s. Your number is %d\n" % (name, num))
|
||||
>>> traceprintf("Your result is 90%%.")
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Notice how string formatting is being done in Python instead of C.
|
||||
The caveat is the strings passed must be safe to use in C though.
|
||||
For example if name was to contain a "%" it should be double escaped in order to avoid unpredictable
|
||||
behaviour:
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
<pre>
|
||||
>>> traceprintf("Your result is 90%.\n") # unpredictable behaviour
|
||||
>>> traceprintf("Your result is 90%%.\n") # good
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Read on for further solutions.
|
||||
</p>
|
||||
|
||||
|
||||
<H2><a name="Varargs_nn5"></a>13.4 Argument replacement using %varargs</H2>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ During compilation, SWIG may generate a variety of warning messages. For exampl
|
|||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:16: Warning(501): Overloaded declaration ignored. bar(double)
|
||||
example.i:15: Warning(501): Previous declaration is bar(int)
|
||||
example.i:16: Warning 501: Overloaded declaration ignored. bar(double)
|
||||
example.i:15: Warning 501: Previous declaration is bar(int)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
|
@ -344,7 +344,7 @@ These can be overridden using command line options, for example:
|
|||
$ swig -python -Fstandard example.i
|
||||
example.i:4: Syntax error in input.
|
||||
$ swig -python -Fmicrosoft example.i
|
||||
example.i(4): Syntax error in input.
|
||||
example.i(4) : Syntax error in input.
|
||||
</pre></div>
|
||||
|
||||
<H2><a name="Warnings_nn9"></a>14.9 Warning number reference</H2>
|
||||
|
|
@ -399,18 +399,20 @@ example.i(4): Syntax error in input.
|
|||
<li>308. Namespace alias '<em>name</em>' not allowed here. Assuming '<em>name</em>'
|
||||
<li>309. [private | protected] inheritance ignored.
|
||||
<li>310. Template '<em>name</em>' was already wrapped as '<em>name</em>' (ignored)
|
||||
<li>311. Template partial specialization not supported.
|
||||
<li>312. Nested classes not currently supported (ignored).
|
||||
<li>312. Unnamed nested class not currently supported (ignored).
|
||||
<li>313. Unrecognized extern type "<em>name</em>" (ignored).
|
||||
<li>314. '<em>identifier</em>' is a <em>lang</em> keyword.
|
||||
<li>315. Nothing known about '<em>identifier</em>'.
|
||||
<li>316. Repeated %module directive.
|
||||
<li>317. Specialization of non-template '<em>name</em>'.
|
||||
<li>318. Instantiation of template <em>name</em> is ambiguous. Using <em>templ</em> at <em>file</em>:<em>line</em>
|
||||
<li>318. Instantiation of template '<em>name</em>' is ambiguous, instantiation <em>templ</em> used, instantiation <em>templ</em> ignored.
|
||||
<li>319. No access specifier given for base class <em>name</em> (ignored).
|
||||
<li>320. Explicit template instantiation ignored.
|
||||
<li>321. <em>identifier</em> conflicts with a built-in name.
|
||||
<li>322. Redundant redeclaration of '<em>name</em>'.
|
||||
<li>323. Recursive scope inheritance of '<em>name</em>'.
|
||||
<li>324. Named nested template instantiations not supported. Processing as if no name was given to %template().
|
||||
<li>325. Nested class not currently supported (<em>name</em> ignored).
|
||||
<li>350. operator new ignored.
|
||||
<li>351. operator delete ignored.
|
||||
<li>352. operator+ ignored.
|
||||
|
|
@ -482,8 +484,8 @@ example.i(4): Syntax error in input.
|
|||
<li>469. No or improper directorin typemap defined for <em>type</em>
|
||||
<li>470. Thread/reentrant unsafe wrapping, consider returning by value instead.
|
||||
<li>471. Unable to use return type <em>type</em> in director method
|
||||
<li>474. Method <em>method</em> usage of the optimal attribute in the out typemap at <em>file</em>:<em>line</em> ignored as the following cannot be used to generate optimal code: <em>code</em>
|
||||
<li>475. Multiple calls to <em>method</em> might be generated due to optimal attribute usage in the out typemap at <em>file</em>:<em>line</em>.
|
||||
<li>474. Method <em>method</em> usage of the optimal attribute ignored in the out typemap as the following cannot be used to generate optimal code: <em>code</em>
|
||||
<li>475. Multiple calls to <em>method</em> might be generated due to optimal attribute usage in the out typemap.
|
||||
</ul>
|
||||
|
||||
|
||||
|
|
@ -492,22 +494,22 @@ example.i(4): Syntax error in input.
|
|||
|
||||
|
||||
<ul>
|
||||
<li>501. Overloaded declaration ignored. <em>decl</em>
|
||||
<li>502. Overloaded constructor ignored. <em>decl</em>
|
||||
<li>501. Overloaded declaration ignored. <em>decl</em>. Previous declaration is <em>decl</em>.
|
||||
<li>502. Overloaded constructor ignored. <em>decl</em>. Previous declaration is <em>decl</em>.
|
||||
<li>503. Can't wrap '<em>identifier</em>' unless renamed to a valid identifier.
|
||||
<li>504. Function <em>name</em> must have a return type.
|
||||
<li>505. Variable length arguments discarded.
|
||||
<li>506. Can't wrap varargs with keyword arguments enabled.
|
||||
<li>507. Adding native function <em>name</em> not supported (ignored).
|
||||
<li>508. Declaration of '<em>name</em>' shadows declaration accessible via operator->() at <em>file:line</em>.
|
||||
<li>509. Overloaded <em>declaration</em> is shadowed by <em>declaration</em> at <em>file</em>:<em>line</em>.
|
||||
<li>508. Declaration of '<em>name</em>' shadows declaration accessible via operator->(), previous declaration of'<em>declaration</em>'.
|
||||
<li>509. Overloaded method <em>declaration</em> effectively ignored, as it is shadowed by <em>declaration</em>.
|
||||
<li>510. Friend function '<em>name</em>' ignored.
|
||||
<li>511. Can't use keyword arguments with overloaded functions.
|
||||
<li>512. Overloaded <em>declaration</em> const ignored. Non-const method at <em>file</em>:<em>line</em> used.
|
||||
<li>512. Overloaded method <em>declaration</em> ignored, using non-const method <em>declaration</em> instead.
|
||||
<li>513. Can't generate wrappers for unnamed struct/class.
|
||||
<li>514.
|
||||
<li>515.
|
||||
<li>516. Overloaded method <em>declaration</em> ignored. Method <em>declaration</em> at <em>file</em>:<em>line</em> used.
|
||||
<li>516. Overloaded method <em>declaration</em> ignored, using <em>declaration</em> instead.
|
||||
<li>517.
|
||||
<li>518. Portability warning: File <em>file1</em> will be overwritten by <em>file2</em> on case insensitive filesystems such as Windows' FAT32 and NTFS unless the class/module name is renamed.
|
||||
<li>519. %template() contains no name. Template method ignored: <em>declaration</em>
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ Execute the steps in the order shown and don't use spaces in path names. In fact
|
|||
<ol>
|
||||
<li>
|
||||
Download the following packages from the <a href="http://www.mingw.org/download.shtml">MinGW download page</a>
|
||||
or <a href="http://sourceforge.net/project/showfiles.php?group_id=2435">MinGW SourceForge download page</a>.
|
||||
or <a href="http://sourceforge.net/projects/mingw/files/">MinGW SourceForge download page</a>.
|
||||
Note that at the time of writing, the majority of these are in the Current
|
||||
release list and some are in the Snapshot or Previous release list.
|
||||
<ul>
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ python_clean:
|
|||
rm -f *_wrap* *~ .~* mypython@EXEEXT@ *.pyc
|
||||
rm -f core @EXTRA_CLEAN@
|
||||
rm -f *.@OBJEXT@ *@SO@ *@PYTHON_SO@
|
||||
if [ -f runme.py ]; then (rm -f runme3.py runme3.py.bak;) fi;
|
||||
if [ -f runme.py ]; then rm -f runme3.py runme3.py.bak; fi
|
||||
|
||||
|
||||
##################################################################
|
||||
|
|
@ -336,12 +336,13 @@ OCTAVE_SO = @OCTAVE_SO@
|
|||
|
||||
# ----------------------------------------------------------------
|
||||
# Build a C dynamically loadable module
|
||||
# Note: Octave requires C++ compiler when compiling C wrappers
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
octave: $(SRCS)
|
||||
$(SWIG) -octave $(SWIGOPT) $(INTERFACEPATH)
|
||||
$(CXX) -g -c $(CCSHARED) $(CXXFLAGS) $(ICXXSRCS) $(CXXSRCS) $(INCLUDES) -I$(OCTAVE_INCLUDE)
|
||||
$(CC) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(INCLUDES) $(OCTAVE_INCLUDE)
|
||||
$(CC) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(INCLUDES)
|
||||
$(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
|
|
@ -1124,11 +1125,11 @@ RRSRC = $(INTERFACE:.i=.R)
|
|||
|
||||
r: $(SRCS)
|
||||
$(SWIG) -r $(SWIGOPT) $(INTERFACEPATH)
|
||||
+( PKG_LIBS="$(SRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) )
|
||||
+( PKG_LIBS="$(SRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -fPIC -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) )
|
||||
|
||||
r_cpp: $(CXXSRCS)
|
||||
$(SWIG) -c++ -r $(SWIGOPT) -o $(RCXXSRCS) $(INTERFACEPATH)
|
||||
+( PKG_LIBS="$(CXXSRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) )
|
||||
+( PKG_LIBS="$(CXXSRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -fPIC -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) )
|
||||
|
||||
r_clean:
|
||||
rm -f *_wrap* *~ .~*
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ extraction.
|
|||
|
||||
<ul>
|
||||
<li> <a href="example.c">example.c</a> (C Source)
|
||||
<li> <a href="example.i">example.i</a> (Swig interface)
|
||||
<li> <a href="example.i">example.i</a> (SWIG interface)
|
||||
<li> <a href="runme.java">runme.java</a> (Java program)
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -66,24 +66,6 @@ The examples have been extensively tested on the following platforms:
|
|||
|
||||
Please see the <a href="../../Doc/Manual/Windows.html">Windows</a> page in the main manual for information on using the examples on Windows. <p>
|
||||
|
||||
The most recent version of Perl used for testing is as follows:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
% perl -version
|
||||
This is perl, v5.6.0 built for sun4-solaris
|
||||
|
||||
Copyright 1987-2000, Larry Wall
|
||||
|
||||
Perl may be copied only under the terms of either the Artistic License or the
|
||||
GNU General Public License, which may be found in the Perl 5.0 source kit.
|
||||
|
||||
Complete documentation for Perl, including FAQ lists, should be found on
|
||||
this system using `man perl' or `perldoc perl'. If you have access to the
|
||||
Internet, point your browser at http://www.perl.com/, the Perl Home Page.
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Due to wide variations in the Perl C API and differences between versions such as the ActivePerl release for Windows,
|
||||
the code generated by SWIG is extremely messy. We have made every attempt to maintain compatibility with
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ extraction.
|
|||
|
||||
<ul>
|
||||
<li> <a href="example.c">example.c</a> (C Source)
|
||||
<li> <a href="example.i">example.i</a> (Swig interface)
|
||||
<li> <a href="example.i">example.i</a> (SWIG interface)
|
||||
<li> <a href="runme.pl">runme.pl</a> (Perl Script)
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
22
Examples/php/callback/Makefile
Normal file
22
Examples/php/callback/Makefile
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS = -lm
|
||||
SWIGOPT =
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp
|
||||
|
||||
static::
|
||||
$(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' php_cpp_static
|
||||
|
||||
clean::
|
||||
$(MAKE) -f $(TOP)/Makefile php_clean
|
||||
rm -f $(TARGET).php
|
||||
|
||||
check: all
|
||||
$(MAKE) -f $(TOP)/Makefile php_run
|
||||
4
Examples/php/callback/example.cxx
Normal file
4
Examples/php/callback/example.cxx
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
|
||||
22
Examples/php/callback/example.h
Normal file
22
Examples/php/callback/example.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* File : example.h */
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class Callback {
|
||||
public:
|
||||
virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
|
||||
virtual void run() { std::cout << "Callback::run()" << std::endl; }
|
||||
};
|
||||
|
||||
|
||||
class Caller {
|
||||
private:
|
||||
Callback *_callback;
|
||||
public:
|
||||
Caller(): _callback(0) {}
|
||||
~Caller() { delCallback(); }
|
||||
void delCallback() { delete _callback; _callback = 0; }
|
||||
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
|
||||
void call() { if (_callback) _callback->run(); }
|
||||
};
|
||||
|
||||
13
Examples/php/callback/example.i
Normal file
13
Examples/php/callback/example.i
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* File : example.i */
|
||||
%module(directors="1") example
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "std_string.i"
|
||||
|
||||
/* turn on director wrapping Callback */
|
||||
%feature("director") Callback;
|
||||
|
||||
%include "example.h"
|
||||
|
||||
19
Examples/php/callback/index.html
Normal file
19
Examples/php/callback/index.html
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SWIG:Examples:php:callback</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
|
||||
|
||||
<tt>SWIG/Examples/php/callback/</tt>
|
||||
<hr>
|
||||
|
||||
<H2>Implementing C++ callbacks in PHP</H2>
|
||||
|
||||
<p>
|
||||
This example illustrates how to use directors to implement C++ callbacks in PHP.
|
||||
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
||||
47
Examples/php/callback/runme.php
Normal file
47
Examples/php/callback/runme.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
# This file illustrates the cross language polymorphism using directors.
|
||||
|
||||
require("example.php");
|
||||
|
||||
# Class, which overwrites Callback::run().
|
||||
|
||||
class PhpCallback extends Callback {
|
||||
function run() {
|
||||
print "PhpCallback.run()\n";
|
||||
}
|
||||
};
|
||||
|
||||
# Create an Caller instance
|
||||
|
||||
$caller = new Caller();
|
||||
|
||||
# Add a simple C++ callback (caller owns the callback, so
|
||||
# we disown it first by clearing the .thisown flag).
|
||||
|
||||
print "Adding and calling a normal C++ callback\n";
|
||||
print "----------------------------------------\n";
|
||||
|
||||
$callback = new Callback();
|
||||
$callback->thisown = 0;
|
||||
$caller->setCallback($callback);
|
||||
$caller->call();
|
||||
$caller->delCallback();
|
||||
|
||||
print "\n";
|
||||
print "Adding and calling a PHP callback\n";
|
||||
print "------------------------------------\n";
|
||||
|
||||
# Add a PHP callback.
|
||||
|
||||
$callback = new PhpCallback();
|
||||
$callback->thisown = 0;
|
||||
$caller->setCallback($callback);
|
||||
$caller->call();
|
||||
$caller->delCallback();
|
||||
|
||||
# All done.
|
||||
|
||||
print "php exit\n";
|
||||
|
||||
?>
|
||||
|
|
@ -1,16 +1,18 @@
|
|||
# see top-level Makefile.in
|
||||
# (see also top-level configure.in kludge)
|
||||
callback
|
||||
class
|
||||
constants
|
||||
cpointer
|
||||
disown
|
||||
enum
|
||||
extend
|
||||
funcptr
|
||||
overloading
|
||||
pointer
|
||||
pragmas
|
||||
reference
|
||||
proxy
|
||||
reference
|
||||
simple
|
||||
sync
|
||||
value
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ CXXSRCS = example.cxx
|
|||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS =
|
||||
SWIGOPT = -noproxy
|
||||
SWIGOPT =
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
|
|
|
|||
|
|
@ -1,22 +1,20 @@
|
|||
<?php
|
||||
|
||||
# This file illustrates the low-level C++ interface
|
||||
# created by SWIG. In this case, all of our C++ classes
|
||||
# get converted into function calls.
|
||||
# This example illustrates how member variables are wrapped.
|
||||
|
||||
require("example.php");
|
||||
|
||||
# ----- Object creation -----
|
||||
|
||||
print "Creating some objects:\n";
|
||||
$c = new_Circle(10);
|
||||
print " Created circle $c\n";
|
||||
$s = new_Square(10);
|
||||
print " Created square $s\n";
|
||||
$c = new Circle(10);
|
||||
print " Created circle\n";
|
||||
$s = new Square(10);
|
||||
print " Created square\n";
|
||||
|
||||
# ----- Access a static member -----
|
||||
|
||||
print "\nA total of " . nshapes() . " shapes were created\n";
|
||||
print "\nA total of " . Shape::get_nshapes() . " shapes were created\n";
|
||||
|
||||
# ----- Member data access -----
|
||||
|
||||
|
|
@ -24,14 +22,14 @@ print "\nA total of " . nshapes() . " shapes were created\n";
|
|||
# Note: methods in the base class Shape are used since
|
||||
# x and y are defined there.
|
||||
|
||||
Shape_x_set($c, 20);
|
||||
Shape_y_set($c, 30);
|
||||
Shape_x_set($s,-10);
|
||||
Shape_y_set($s,5);
|
||||
$c->x = 20;
|
||||
$c->y = 30;
|
||||
$s->x = -10;
|
||||
$s->y = 5;
|
||||
|
||||
print "\nHere is their current position:\n";
|
||||
print " Circle = (" . Shape_x_get($c) . "," . Shape_y_get($c) . ")\n";
|
||||
print " Square = (" . Shape_x_get($s) . "," . Shape_y_get($s) . ")\n";
|
||||
print " Circle = ({$c->x},{$c->y})\n";
|
||||
print " Square = ({$s->x},{$s->y})\n";
|
||||
|
||||
# ----- Call some methods -----
|
||||
|
||||
|
|
@ -39,18 +37,16 @@ print " Square = (" . Shape_x_get($s) . "," . Shape_y_get($s) . ")\n";
|
|||
# invoke the appropriate virtual method on each object.
|
||||
print "\nHere are some properties of the shapes:\n";
|
||||
foreach (array($c,$s) as $o) {
|
||||
print " $o\n";
|
||||
print " area = " . Shape_area($o) . "\n";
|
||||
print " perimeter = " . Shape_perimeter($o) . "\n";
|
||||
}
|
||||
print " ". get_class($o) . "\n";
|
||||
print " area = {$o->area()}\n";
|
||||
print " perimeter = {$o->perimeter()}\n";
|
||||
}
|
||||
|
||||
# ----- Delete everything -----
|
||||
|
||||
print "\nGuess I'll clean up now\n";
|
||||
|
||||
# Note: this invokes the virtual destructor
|
||||
#delete_Shape($c);
|
||||
#delete_Shape($s);
|
||||
$c = NULL;
|
||||
$s = NULL;
|
||||
|
||||
|
|
@ -58,7 +54,7 @@ $s = NULL;
|
|||
# the square.
|
||||
$o = NULL;
|
||||
|
||||
print nshapes() . " shapes remain\n";
|
||||
print Shape::get_nshapes() . " shapes remain\n";
|
||||
print "Goodbye\n";
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
# Now get the result
|
||||
$r = intp_value($c);
|
||||
|
||||
print " 38 + 42 = $r\n";
|
||||
print " 37 + 42 = $r\n";
|
||||
|
||||
# Clean up the pointers
|
||||
delete_intp($a);
|
||||
|
|
|
|||
22
Examples/php/extend/Makefile
Normal file
22
Examples/php/extend/Makefile
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS = -lm
|
||||
SWIGOPT =
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp
|
||||
|
||||
static::
|
||||
$(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' php_cpp_static
|
||||
|
||||
clean::
|
||||
$(MAKE) -f $(TOP)/Makefile php_clean
|
||||
rm -f $(TARGET).php
|
||||
|
||||
check: all
|
||||
$(MAKE) -f $(TOP)/Makefile php_run
|
||||
4
Examples/php/extend/example.cxx
Normal file
4
Examples/php/extend/example.cxx
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/* File : example.cxx */
|
||||
|
||||
#include "example.h"
|
||||
|
||||
56
Examples/php/extend/example.h
Normal file
56
Examples/php/extend/example.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* File : example.h */
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
|
||||
class Employee {
|
||||
private:
|
||||
std::string name;
|
||||
public:
|
||||
Employee(const char* n): name(n) {}
|
||||
virtual std::string getTitle() { return getPosition() + " " + getName(); }
|
||||
virtual std::string getName() { return name; }
|
||||
virtual std::string getPosition() const { return "Employee"; }
|
||||
virtual ~Employee() { printf("~Employee() @ %p\n", this); }
|
||||
};
|
||||
|
||||
|
||||
class Manager: public Employee {
|
||||
public:
|
||||
Manager(const char* n): Employee(n) {}
|
||||
virtual std::string getPosition() const { return "Manager"; }
|
||||
};
|
||||
|
||||
|
||||
class EmployeeList {
|
||||
std::vector<Employee*> list;
|
||||
public:
|
||||
EmployeeList() {
|
||||
list.push_back(new Employee("Bob"));
|
||||
list.push_back(new Employee("Jane"));
|
||||
list.push_back(new Manager("Ted"));
|
||||
}
|
||||
void addEmployee(Employee *p) {
|
||||
list.push_back(p);
|
||||
std::cout << "New employee added. Current employees are:" << std::endl;
|
||||
std::vector<Employee*>::iterator i;
|
||||
for (i=list.begin(); i!=list.end(); i++) {
|
||||
std::cout << " " << (*i)->getTitle() << std::endl;
|
||||
}
|
||||
}
|
||||
const Employee *get_item(int i) {
|
||||
return list[i];
|
||||
}
|
||||
~EmployeeList() {
|
||||
std::vector<Employee*>::iterator i;
|
||||
std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl;
|
||||
for (i=list.begin(); i!=list.end(); i++) {
|
||||
delete *i;
|
||||
}
|
||||
std::cout << "~EmployeeList empty." << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
15
Examples/php/extend/example.i
Normal file
15
Examples/php/extend/example.i
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* File : example.i */
|
||||
%module(directors="1") example
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "std_vector.i"
|
||||
%include "std_string.i"
|
||||
|
||||
/* turn on director wrapping for Manager */
|
||||
%feature("director") Employee;
|
||||
%feature("director") Manager;
|
||||
|
||||
%include "example.h"
|
||||
|
||||
19
Examples/php/extend/index.html
Normal file
19
Examples/php/extend/index.html
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SWIG:Examples:php:extend</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
|
||||
|
||||
<tt>SWIG/Examples/php/extend/</tt>
|
||||
<hr>
|
||||
|
||||
<H2>Extending a simple C++ class in PHP</H2>
|
||||
|
||||
<p>
|
||||
This example illustrates the extending of a C++ class with cross language polymorphism.
|
||||
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
||||
76
Examples/php/extend/runme.php
Normal file
76
Examples/php/extend/runme.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
# This file illustrates the cross language polymorphism using directors.
|
||||
|
||||
require("example.php");
|
||||
|
||||
# CEO class, which overrides Employee::getPosition().
|
||||
|
||||
class CEO extends Manager {
|
||||
function getPosition() {
|
||||
return "CEO";
|
||||
}
|
||||
}
|
||||
|
||||
# Create an instance of our employee extension class, CEO. The calls to
|
||||
# getName() and getPosition() are standard, the call to getTitle() uses
|
||||
# the director wrappers to call CEO.getPosition.
|
||||
|
||||
$e = new CEO("Alice");
|
||||
print $e->getName() . " is a " . $e->getPosition() . "\n";
|
||||
printf("Just call her \"%s\"\n", $e->getTitle());
|
||||
print "----------------------\n";
|
||||
|
||||
# Create a new EmployeeList instance. This class does not have a C++
|
||||
# director wrapper, but can be used freely with other classes that do.
|
||||
|
||||
$list = new EmployeeList();
|
||||
|
||||
# EmployeeList owns its items, so we must surrender ownership of objects
|
||||
# we add. This involves first clearing the ->disown member to tell the
|
||||
# C++ director to start reference counting.
|
||||
|
||||
$e->thisown = 0;
|
||||
$list->addEmployee($e);
|
||||
print "----------------------\n";
|
||||
|
||||
# Now we access the first four items in list (three are C++ objects that
|
||||
# EmployeeList's constructor adds, the last is our CEO). The virtual
|
||||
# methods of all these instances are treated the same. For items 0, 1, and
|
||||
# 2, both all methods resolve in C++. For item 3, our CEO, getTitle calls
|
||||
# getPosition which resolves in PHP. The call to getPosition is
|
||||
# slightly different, however, from the e.getPosition() call above, since
|
||||
# now the object reference has been "laundered" by passing through
|
||||
# EmployeeList as an Employee*. Previously, PHP resolved the call
|
||||
# immediately in CEO, but now PHP thinks the object is an instance of
|
||||
# class Employee (actually EmployeePtr). So the call passes through the
|
||||
# Employee proxy class and on to the C wrappers and C++ director,
|
||||
# eventually ending up back at the CEO implementation of getPosition().
|
||||
# The call to getTitle() for item 3 runs the C++ Employee::getTitle()
|
||||
# method, which in turn calls getPosition(). This virtual method call
|
||||
# passes down through the C++ director class to the PHP implementation
|
||||
# in CEO. All this routing takes place transparently.
|
||||
|
||||
print "(position, title) for items 0-3:\n";
|
||||
|
||||
printf(" %s, \"%s\"\n", $list->get_item(0)->getPosition(), $list->get_item(0)->getTitle());
|
||||
printf(" %s, \"%s\"\n", $list->get_item(1)->getPosition(), $list->get_item(1)->getTitle());
|
||||
printf(" %s, \"%s\"\n", $list->get_item(2)->getPosition(), $list->get_item(2)->getTitle());
|
||||
printf(" %s, \"%s\"\n", $list->get_item(3)->getPosition(), $list->get_item(3)->getTitle());
|
||||
print "----------------------\n";
|
||||
|
||||
# Time to delete the EmployeeList, which will delete all the Employee*
|
||||
# items it contains. The last item is our CEO, which gets destroyed as its
|
||||
# reference count goes to zero. The PHP destructor runs, and is still
|
||||
# able to call the getName() method since the underlying C++ object still
|
||||
# exists. After this destructor runs the remaining C++ destructors run as
|
||||
# usual to destroy the object.
|
||||
|
||||
unset($list);
|
||||
print "----------------------\n";
|
||||
|
||||
# All done.
|
||||
|
||||
print "php exit\n";
|
||||
|
||||
?>
|
||||
|
|
@ -4,7 +4,7 @@ CXXSRCS = example.cxx
|
|||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS =
|
||||
SWIGOPT = -noproxy
|
||||
SWIGOPT =
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ Vector operator+(const Vector &a, const Vector &b) {
|
|||
return r;
|
||||
}
|
||||
|
||||
char *Vector::print() {
|
||||
char *Vector::as_string() {
|
||||
static char temp[512];
|
||||
sprintf(temp,"Vector %p (%g,%g,%g)", this, x,y,z);
|
||||
return temp;
|
||||
|
|
@ -47,4 +47,3 @@ int VectorArray::size() {
|
|||
printf("VectorArray: size %d self=%p\n",maxsize,this);
|
||||
return maxsize;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ public:
|
|||
Vector() : x(0), y(0), z(0) { };
|
||||
Vector(double x, double y, double z) : x(x), y(y), z(z) { };
|
||||
friend Vector operator+(const Vector &a, const Vector &b);
|
||||
char *print();
|
||||
char *as_string();
|
||||
};
|
||||
|
||||
class VectorArray {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
/* File : example.i */
|
||||
|
||||
/* This file has a few "typical" uses of C++ references. */
|
||||
/* This example has nothing to do with references but the name is used by all
|
||||
* the other languages so it's hard to rename to something more meaningful.
|
||||
*
|
||||
* Mostly it shows how to use %extend.
|
||||
*/
|
||||
|
||||
%module example
|
||||
|
||||
|
|
@ -12,7 +16,7 @@ class Vector {
|
|||
public:
|
||||
Vector(double x, double y, double z);
|
||||
~Vector();
|
||||
char *print();
|
||||
char *as_string();
|
||||
};
|
||||
|
||||
/* This helper function calls an overloaded operator */
|
||||
|
|
@ -41,4 +45,3 @@ public:
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
<?php
|
||||
|
||||
# This file illustrates the manipulation of C++ references in Php.
|
||||
# This uses the low-level interface. Proxy classes work differently.
|
||||
# This file illustrates the manipulation of C++ references in PHP.
|
||||
|
||||
require "example.php";
|
||||
|
||||
# ----- Object creation -----
|
||||
|
||||
print "Creating some objects:\n";
|
||||
$a = new_Vector(3,4,5);
|
||||
$b = new_Vector(10,11,12);
|
||||
$a = new Vector(3, 4, 5);
|
||||
$b = new Vector(10, 11, 12);
|
||||
|
||||
print " Created a: $a " . Vector_print($a) . "\n";
|
||||
print " Created b: $b " . Vector_print($b) . "\n";
|
||||
print " Created a: {$a->as_string()}\n";
|
||||
print " Created b: {$b->as_string()}\n";
|
||||
|
||||
# ----- Call an overloaded operator -----
|
||||
|
||||
|
|
@ -23,56 +22,28 @@ print " Created b: $b " . Vector_print($b) . "\n";
|
|||
# It returns a new allocated object.
|
||||
|
||||
print "Adding a+b\n";
|
||||
$c = addv($a,$b);
|
||||
print " a+b =". Vector_print($c)."\n";
|
||||
|
||||
# Note: Unless we free the result, a memory leak will occur
|
||||
$c = None;
|
||||
$c = example::addv($a, $b);
|
||||
print " a+b ={$c->as_string()}\n";
|
||||
|
||||
# ----- Create a vector array -----
|
||||
|
||||
# Note: Using the high-level interface here
|
||||
print "Creating an array of vectors\n";
|
||||
$va = new_VectorArray(10);
|
||||
$va = new VectorArray(10);
|
||||
|
||||
print " va: $va size=".VectorArray_size($va)."\n";
|
||||
print " va: size={$va->size()}\n";
|
||||
|
||||
# ----- Set some values in the array -----
|
||||
|
||||
# These operators copy the value of $a and $b to the vector array
|
||||
VectorArray_set($va,0,$a);
|
||||
VectorArray_set($va,1,$b);
|
||||
|
||||
VectorArray_get($va,0);
|
||||
# This will work, but it will cause a memory leak!
|
||||
|
||||
VectorArray_set($va,2,addv($a,$b));
|
||||
|
||||
# The non-leaky way to do it
|
||||
|
||||
$c = addv($a,$b);
|
||||
VectorArray_set($va,3,$c);
|
||||
$c = None;
|
||||
$va->set(0, $a);
|
||||
$va->set(1, $b);
|
||||
$va->set(2, addv($a, $b));
|
||||
|
||||
# Get some values from the array
|
||||
|
||||
print "Getting some array values\n";
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
print "do $i\n";
|
||||
print " va($i) = ". Vector_print(VectorArray_get($va,$i)). "\n";
|
||||
print " va[$i] = {$va->get($i)->as_string()}\n";
|
||||
}
|
||||
|
||||
# Watch under resource meter to check on this
|
||||
#print "Making sure we don't leak memory.\n";
|
||||
#for ($i = 0; $i < 1000000; $i++) {
|
||||
# $c = VectorArray_get($va,$i % 10);
|
||||
#}
|
||||
|
||||
# ----- Clean up -----
|
||||
print "Cleaning up\n";
|
||||
# wants fixing FIXME
|
||||
$va = None;
|
||||
$a = None;
|
||||
$b = None;
|
||||
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
/* File : example.h */
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
class Callback {
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ extraction.
|
|||
|
||||
<ul>
|
||||
<li> <a href="example.c">example.c</a> (C Source)
|
||||
<li> <a href="example.i">example.i</a> (Swig interface)
|
||||
<li> <a href="example.i">example.i</a> (SWIG interface)
|
||||
<li> <a href="example.py">example.py</a> (Python Script)
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ extern int gcd(int x, int y);
|
|||
if (TYPE($input) != T_ARRAY) {
|
||||
SWIG_exception(SWIG_ValueError, "Expected an array");
|
||||
}
|
||||
$1 = RARRAY($input)->len;
|
||||
$1 = RARRAY_LEN($input);
|
||||
if ($1 == 0) {
|
||||
SWIG_exception(SWIG_ValueError, "List must contain at least 1 element");
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ extern int gcdmain(int argc, char *argv[]);
|
|||
SWIG_exception(SWIG_ValueError, "Expected a string");
|
||||
}
|
||||
$1 = STR2CSTR($input);
|
||||
$2 = RSTRING($input)->len;
|
||||
$2 = RSTRING_LEN($input);
|
||||
}
|
||||
|
||||
extern int count(char *bytes, int len, char c);
|
||||
|
|
@ -61,7 +61,7 @@ extern int count(char *bytes, int len, char c);
|
|||
SWIG_exception(SWIG_ValueError,"Expected a string");
|
||||
}
|
||||
temp = STR2CSTR($input);
|
||||
$2 = RSTRING($input)->len;
|
||||
$2 = RSTRING_LEN($input);
|
||||
$1 = (char *) malloc($2+1);
|
||||
memmove($1,temp,$2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ extraction.
|
|||
|
||||
<ul>
|
||||
<li> <a href="example.c">example.c</a> (C Source)
|
||||
<li> <a href="example.i">example.i</a> (Swig interface)
|
||||
<li> <a href="example.i">example.i</a> (SWIG interface)
|
||||
<li> <a href="runme.rb">runme.rb</a> (Ruby Script)
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ extraction.
|
|||
|
||||
<ul>
|
||||
<li> <a href="example.c">example.c</a> (C Source)
|
||||
<li> <a href="example.i">example.i</a> (Swig interface)
|
||||
<li> <a href="example.i">example.i</a> (SWIG interface)
|
||||
<li> <a href="runme.tcl">runme.tcl</a> (Tcl Script)
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -89,8 +89,12 @@ SKIP_CPP_STD_CASES = Yes
|
|||
|
||||
include $(srcdir)/../common.mk
|
||||
|
||||
# Overridden variables here
|
||||
# SWIGOPT += -debug-module 4
|
||||
|
||||
# Custom tests - tests with additional commandline options
|
||||
# none!
|
||||
|
||||
# Rules for the different types of tests
|
||||
%.cpptest:
|
||||
$(setup)
|
||||
|
|
@ -110,9 +114,9 @@ include $(srcdir)/../common.mk
|
|||
# Runs the testcase. A testcase is only run if
|
||||
# a file is found which has _runme.lisp appended after the testcase name.
|
||||
run_testcase = \
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then ( \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(ALLEGROCLBIN) -batch -s $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX);) \
|
||||
fi;
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(ALLEGROCLBIN) -batch -s $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
|
||||
fi
|
||||
|
||||
%.clean:
|
||||
@rm -f $*.cl
|
||||
|
|
|
|||
33
Examples/test-suite/catches.i
Normal file
33
Examples/test-suite/catches.i
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
%module catches
|
||||
|
||||
%{
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
%}
|
||||
|
||||
%include <exception.i> // for throws(...) typemap
|
||||
|
||||
%catches(int, const char *, const ThreeException&) test_catches(int i);
|
||||
%catches(int, ...) test_exception_specification(int i); // override the exception specification
|
||||
%catches(...) test_catches_all(int i);
|
||||
|
||||
%inline %{
|
||||
struct ThreeException {};
|
||||
void test_catches(int i) {
|
||||
if (i == 1) {
|
||||
throw int(1);
|
||||
} else if (i == 2) {
|
||||
throw (const char *)"two";
|
||||
} else if (i == 3) {
|
||||
throw ThreeException();
|
||||
}
|
||||
}
|
||||
void test_exception_specification(int i) throw(int, const char *, const ThreeException&) {
|
||||
test_catches(i);
|
||||
}
|
||||
void test_catches_all(int i) {
|
||||
test_catches(i);
|
||||
}
|
||||
%}
|
||||
|
||||
|
|
@ -11,10 +11,14 @@ top_builddir = @top_builddir@
|
|||
|
||||
include $(srcdir)/../common.mk
|
||||
|
||||
# Overridden variables here
|
||||
# no C++ tests for now
|
||||
CPP_TEST_CASES =
|
||||
#C_TEST_CASES +=
|
||||
|
||||
# Custom tests - tests with additional commandline options
|
||||
# none!
|
||||
|
||||
# Rules for the different types of tests
|
||||
%.cpptest:
|
||||
$(setup)
|
||||
|
|
@ -34,9 +38,9 @@ CPP_TEST_CASES =
|
|||
# Runs the testcase. A testcase is only run if
|
||||
# a file is found which has _runme.lisp appended after the testcase name.
|
||||
run_testcase = \
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then ( \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CFFIBIN) -batch -s $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX);) \
|
||||
fi;
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CFFIBIN) -batch -s $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
|
||||
fi
|
||||
|
||||
# Clean: (does nothing, we dont generate extra cffi code)
|
||||
%.clean:
|
||||
|
|
|
|||
|
|
@ -149,6 +149,18 @@ const char global_const_char_array2[sizeof(CPLUSPLUS_MSG)+1] = CPLUSPLUS_MSG;
|
|||
%inline %{
|
||||
|
||||
// char *& tests
|
||||
char *&GetCharPointerRef() {
|
||||
static char str[] = CPLUSPLUS_MSG;
|
||||
static char *ptr = str;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool SetCharPointerRef(char *&str, unsigned int number) {
|
||||
static char static_str[] = CPLUSPLUS_MSG;
|
||||
strcpy(static_str, str);
|
||||
return check(static_str, number);
|
||||
}
|
||||
|
||||
const char *&GetConstCharPointerRef() {
|
||||
static const char str[] = CPLUSPLUS_MSG;
|
||||
static const char *ptr = str;
|
||||
|
|
|
|||
|
|
@ -23,70 +23,73 @@ EXTRA_TEST_CASES += chicken_ext_test.externaltest
|
|||
|
||||
include $(srcdir)/../common.mk
|
||||
|
||||
|
||||
# Overridden variables here
|
||||
SWIGOPT += -nounit
|
||||
|
||||
# Custom tests - tests with additional commandline options
|
||||
# If there exists a PROXYSUFFIX runme file, we also generate the wrapper
|
||||
# with the -proxy argument
|
||||
%.cppproxy: SWIGOPT += -proxy
|
||||
%.cppproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
|
||||
|
||||
%.cproxy: SWIGOPT += -proxy
|
||||
%.cproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
|
||||
|
||||
%.multiproxy: SWIGOPT += -proxy -noclosuses
|
||||
%.multiproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
|
||||
|
||||
# Rules for the different types of tests
|
||||
%.cpptest:
|
||||
$(setup)
|
||||
+$(swig_and_compile_cpp)
|
||||
$(run_testcase)
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then ( \
|
||||
$(MAKE) $*.cppproxy; ) \
|
||||
fi;
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then \
|
||||
$(MAKE) $*.cppproxy; \
|
||||
fi
|
||||
|
||||
%.ctest:
|
||||
$(setup)
|
||||
+$(swig_and_compile_c)
|
||||
$(run_testcase)
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then ( \
|
||||
$(MAKE) $*.cproxy; ) \
|
||||
fi;
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then \
|
||||
$(MAKE) $*.cproxy; \
|
||||
fi
|
||||
|
||||
%.multicpptest:
|
||||
$(setup)
|
||||
+$(swig_and_compile_multi_cpp)
|
||||
$(run_testcase)
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then ( \
|
||||
$(MAKE) $*.multiproxy; ) \
|
||||
fi;
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then \
|
||||
$(MAKE) $*.multiproxy; \
|
||||
fi
|
||||
|
||||
%.externaltest:
|
||||
$(setup)
|
||||
+$(swig_and_compile_external)
|
||||
$(run_testcase)
|
||||
|
||||
# Runs the testcase. A testcase is only run if
|
||||
# a file is found which has _runme.scm appended after the testcase name.
|
||||
run_testcase = \
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then ( \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CHICKEN_CSI) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX);) \
|
||||
fi;
|
||||
|
||||
# If there exists a PROXYSUFFIX runme file, we also generate the wrapper
|
||||
# with the -proxy argument
|
||||
%.cppproxy: SWIGOPT += -proxy
|
||||
%.cppproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
|
||||
%.cppproxy:
|
||||
echo "$(ACTION)ing testcase $* (with run test) under chicken with -proxy"
|
||||
+$(swig_and_compile_cpp)
|
||||
$(run_testcase)
|
||||
|
||||
%.cproxy: SWIGOPT += -proxy
|
||||
%.cproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
|
||||
%.cproxy:
|
||||
echo "$(ACTION)ing testcase $* (with run test) under chicken with -proxy"
|
||||
+$(swig_and_compile_c)
|
||||
$(run_testcase)
|
||||
|
||||
%.multiproxy: SWIGOPT += -proxy -noclosuses
|
||||
%.multiproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
|
||||
%.multiproxy:
|
||||
echo "$(ACTION)ing testcase $* (with run test) under chicken with -proxy"
|
||||
+$(swig_and_compile_multi_cpp)
|
||||
$(run_testcase)
|
||||
|
||||
# Runs the testcase. A testcase is only run if
|
||||
# a file is found which has _runme.scm appended after the testcase name.
|
||||
run_testcase = \
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CHICKEN_CSI) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
|
||||
fi
|
||||
|
||||
# Clean
|
||||
%.clean:
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,14 @@ top_builddir = @top_builddir@
|
|||
|
||||
include $(srcdir)/../common.mk
|
||||
|
||||
# Overridden variables here
|
||||
# no C++ tests for now
|
||||
CPP_TEST_CASES =
|
||||
#C_TEST_CASES +=
|
||||
|
||||
# Custom tests - tests with additional commandline options
|
||||
# none!
|
||||
|
||||
# Rules for the different types of tests
|
||||
%.cpptest:
|
||||
$(setup)
|
||||
|
|
@ -34,9 +38,9 @@ CPP_TEST_CASES =
|
|||
# Runs the testcase. A testcase is only run if
|
||||
# a file is found which has _runme.lisp appended after the testcase name.
|
||||
run_testcase = \
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then ( \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CLISPBIN) -batch -s $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX);) \
|
||||
fi;
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CLISPBIN) -batch -s $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
|
||||
fi
|
||||
|
||||
# Clean: (does nothing, we dont generate extra clisp code)
|
||||
%.clean:
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
# b) Define rules for %.ctest, %.cpptest, %.multicpptest and %.clean.
|
||||
# c) Define srcdir, top_srcdir and top_builddir (these are the
|
||||
# equivalent to configure's variables of the same name).
|
||||
# 3) One off special commandline options can be achieved by adding a
|
||||
# test case to CUSTOM_TEST_CASES and defining rules to run and test.
|
||||
# 3) One off special commandline options for a testcase can be added.
|
||||
# See custom tests below.
|
||||
#
|
||||
# The 'check' target runs the testcases including SWIG invocation,
|
||||
# C/C++ compilation, target language compilation (if any) and runtime
|
||||
|
|
@ -28,12 +28,14 @@
|
|||
# The 'clean' target cleans up.
|
||||
#
|
||||
# Note that the RUNTOOL, COMPILETOOL and SWIGTOOL variables can be used
|
||||
# for # invoking tools for the runtime tests and target language
|
||||
# for invoking tools for the runtime tests and target language
|
||||
# compiler (eg javac) respectively. For example, valgrind can be used
|
||||
# for memory checking of the runtime tests using:
|
||||
# make RUNTOOL="valgrind --leak-check-full"
|
||||
# make RUNTOOL="valgrind --leak-check=full"
|
||||
# and valgrind can be used when invoking SWIG using:
|
||||
# make SWIGTOOL="valgrind --tool=memcheck"
|
||||
# make SWIGTOOL="valgrind --tool=memcheck --trace-children=yes"
|
||||
# Note: trace-children needed because of preinst-swig shell wrapper
|
||||
# to the swig executable.
|
||||
#
|
||||
# The variables below can be overridden after including this makefile
|
||||
#######################################################################
|
||||
|
|
@ -71,27 +73,25 @@ INTERFACEDIR = ../
|
|||
# Note that any whitespace after the last entry in each list will break make
|
||||
#
|
||||
|
||||
# Broken C++ test cases. (Can be run individually using make testcase.cpptest.)
|
||||
# Broken C++ test cases. (Can be run individually using: make testcase.cpptest)
|
||||
CPP_TEST_BROKEN += \
|
||||
constants \
|
||||
cpp_broken \
|
||||
exception_partial_info \
|
||||
extend_variable \
|
||||
li_std_vector_ptr \
|
||||
namespace_union \
|
||||
nested_struct \
|
||||
overload_complicated \
|
||||
template_default_pointer \
|
||||
template_expr \
|
||||
$(CPP0X_TEST_BROKEN)
|
||||
|
||||
|
||||
# Broken C test cases. (Can be run individually using make testcase.ctest.)
|
||||
# Broken C test cases. (Can be run individually using: make testcase.ctest)
|
||||
C_TEST_BROKEN += \
|
||||
tag_no_clash_with_variable
|
||||
|
||||
|
||||
# C++ test cases. (Can be run individually using make testcase.cpptest.)
|
||||
# C++ test cases. (Can be run individually using: make testcase.cpptest)
|
||||
CPP_TEST_CASES += \
|
||||
$(CPP0X_TEST_CASES) \
|
||||
abstract_access \
|
||||
|
|
@ -119,6 +119,7 @@ CPP_TEST_CASES += \
|
|||
arrays_scope \
|
||||
bloody_hell \
|
||||
bools \
|
||||
catches \
|
||||
cast_operator \
|
||||
casts \
|
||||
char_strings \
|
||||
|
|
@ -190,6 +191,7 @@ CPP_TEST_CASES += \
|
|||
extend_placement \
|
||||
extend_template \
|
||||
extend_template_ns \
|
||||
extern_c \
|
||||
extern_namespace \
|
||||
extern_throws \
|
||||
features \
|
||||
|
|
@ -198,6 +200,7 @@ CPP_TEST_CASES += \
|
|||
fvirtual \
|
||||
global_namespace \
|
||||
global_ns_arg \
|
||||
global_scope_types \
|
||||
global_vars \
|
||||
grouping \
|
||||
ignore_parameter \
|
||||
|
|
@ -222,6 +225,7 @@ CPP_TEST_CASES += \
|
|||
li_typemaps \
|
||||
li_windows \
|
||||
long_long_apply \
|
||||
memberin_extend \
|
||||
member_pointer \
|
||||
member_template \
|
||||
minherit \
|
||||
|
|
@ -238,9 +242,12 @@ CPP_TEST_CASES += \
|
|||
namespace_template \
|
||||
namespace_typedef_class \
|
||||
namespace_typemap \
|
||||
namespace_union \
|
||||
namespace_virtual_method \
|
||||
naturalvar \
|
||||
nested_class \
|
||||
nested_comment \
|
||||
nested_workaround \
|
||||
newobject1 \
|
||||
null_pointer \
|
||||
operator_overload \
|
||||
|
|
@ -255,6 +262,7 @@ CPP_TEST_CASES += \
|
|||
overload_template \
|
||||
overload_template_fast \
|
||||
pointer_reference \
|
||||
preproc_constants \
|
||||
primitive_ref \
|
||||
private_assign \
|
||||
protected_rename \
|
||||
|
|
@ -293,10 +301,13 @@ CPP_TEST_CASES += \
|
|||
smart_pointer_templatevariables \
|
||||
smart_pointer_typedef \
|
||||
special_variables \
|
||||
special_variable_macros \
|
||||
static_array_member \
|
||||
static_const_member \
|
||||
static_const_member_2 \
|
||||
struct_initialization_cpp \
|
||||
struct_value \
|
||||
symbol_clash \
|
||||
template \
|
||||
template_arg_replace \
|
||||
template_arg_scope \
|
||||
|
|
@ -326,6 +337,8 @@ CPP_TEST_CASES += \
|
|||
template_inherit_abstract \
|
||||
template_int_const \
|
||||
template_methods \
|
||||
template_nested \
|
||||
template_nested_typemaps \
|
||||
template_ns \
|
||||
template_ns2 \
|
||||
template_ns3 \
|
||||
|
|
@ -335,6 +348,8 @@ CPP_TEST_CASES += \
|
|||
template_ns_inherit \
|
||||
template_ns_scope \
|
||||
template_partial_arg \
|
||||
template_partial_specialization \
|
||||
template_partial_specialization_typedef \
|
||||
template_qualifier \
|
||||
template_qualifier \
|
||||
template_ref_type \
|
||||
|
|
@ -370,9 +385,11 @@ CPP_TEST_CASES += \
|
|||
typedef_scope \
|
||||
typedef_sizet \
|
||||
typedef_struct \
|
||||
typemap_global_scope \
|
||||
typemap_namespace \
|
||||
typemap_ns_using \
|
||||
typemap_numinputs \
|
||||
typemap_template \
|
||||
typemap_out_optimal \
|
||||
typemap_variables \
|
||||
typemap_various \
|
||||
|
|
@ -396,6 +413,7 @@ CPP_TEST_CASES += \
|
|||
virtual_destructor \
|
||||
virtual_poly \
|
||||
voidtest \
|
||||
wallkw \
|
||||
wrapmacro
|
||||
|
||||
# C++0x test cases.
|
||||
|
|
@ -437,8 +455,10 @@ CPP0X_TEST_BROKEN =
|
|||
CPP_STD_TEST_CASES += \
|
||||
director_string \
|
||||
ignore_template_constructor \
|
||||
li_std_combinations \
|
||||
li_std_deque \
|
||||
li_std_except \
|
||||
li_std_map \
|
||||
li_std_pair \
|
||||
li_std_string \
|
||||
li_std_vector \
|
||||
|
|
@ -455,11 +475,12 @@ CPP_TEST_CASES += ${CPP_STD_TEST_CASES}
|
|||
endif
|
||||
|
||||
|
||||
# C test cases. (Can be run individually using make testcase.ctest.)
|
||||
# C test cases. (Can be run individually using: make testcase.ctest)
|
||||
C_TEST_CASES += \
|
||||
arrays \
|
||||
char_constant \
|
||||
const_const \
|
||||
constant_expr \
|
||||
empty \
|
||||
enums \
|
||||
extern_declaration \
|
||||
|
|
@ -477,24 +498,28 @@ C_TEST_CASES += \
|
|||
li_cpointer \
|
||||
li_math \
|
||||
long_long \
|
||||
memberin_extend_c \
|
||||
name \
|
||||
nested \
|
||||
nested_structs \
|
||||
newobject2 \
|
||||
overload_extend \
|
||||
overload_extendc \
|
||||
preproc \
|
||||
preproc_constants_c \
|
||||
ret_by_value \
|
||||
simple_array \
|
||||
sizeof_pointer \
|
||||
sneaky1 \
|
||||
struct_rename \
|
||||
struct_initialization \
|
||||
typedef_struct \
|
||||
typemap_subst \
|
||||
union_parameter \
|
||||
unions
|
||||
|
||||
|
||||
# Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest.)
|
||||
# Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest)
|
||||
MULTI_CPP_TEST_CASES += \
|
||||
clientdata_prop \
|
||||
imports \
|
||||
|
|
@ -503,10 +528,13 @@ MULTI_CPP_TEST_CASES += \
|
|||
template_typedef_import \
|
||||
multi_import
|
||||
|
||||
# Custom tests - tests with additional commandline options
|
||||
wallkw.cpptest: SWIGOPT += -Wallkw
|
||||
|
||||
|
||||
NOT_BROKEN_TEST_CASES = $(CPP_TEST_CASES:=.cpptest) \
|
||||
$(C_TEST_CASES:=.ctest) \
|
||||
$(MULTI_CPP_TEST_CASES:=.multicpptest) \
|
||||
$(CUSTOM_TEST_CASES:=.customtest) \
|
||||
$(EXTRA_TEST_CASES)
|
||||
|
||||
BROKEN_TEST_CASES = $(CPP_TEST_BROKEN:=.cpptest) \
|
||||
|
|
@ -515,7 +543,6 @@ BROKEN_TEST_CASES = $(CPP_TEST_BROKEN:=.cpptest) \
|
|||
ALL_CLEAN = $(CPP_TEST_CASES:=.clean) \
|
||||
$(C_TEST_CASES:=.clean) \
|
||||
$(MULTI_CPP_TEST_CASES:=.clean) \
|
||||
$(CUSTOM_TEST_CASES:=.clean) \
|
||||
$(CPP_TEST_BROKEN:=.clean) \
|
||||
$(C_TEST_BROKEN:=.clean)
|
||||
|
||||
|
|
|
|||
11
Examples/test-suite/constant_expr.i
Normal file
11
Examples/test-suite/constant_expr.i
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
%module constant_expr;
|
||||
/* Tests of constant expressions. */
|
||||
|
||||
%inline %{
|
||||
|
||||
/* % didn't work in SWIG 1.3.40 and earlier. */
|
||||
const int X = 123%7;
|
||||
#define FOO 12 % 6
|
||||
double d_array[12 % 6];
|
||||
|
||||
%}
|
||||
|
|
@ -121,7 +121,8 @@ int* const globalRet2() {return &GlobalInt;}
|
|||
|
||||
%{
|
||||
static int wxEVT_COMMAND_BUTTON_CLICKEDv;
|
||||
static int **wxEVT_COMMAND_BUTTON_CLICKEDp;
|
||||
static int *wxEVT_COMMAND_BUTTON_CLICKEDp;
|
||||
static int **wxEVT_COMMAND_BUTTON_CLICKEDpp = &wxEVT_COMMAND_BUTTON_CLICKEDp;
|
||||
#if defined(SWIGR)
|
||||
#undef lang1 /* conflicts with symbol in R internals */
|
||||
#endif
|
||||
|
|
@ -137,7 +138,7 @@ char *langs[] ={ lang1 };
|
|||
#define EWXWEXPORT_VAR
|
||||
|
||||
const int* wxEVENT_COMMAND_BUTTON_CLICKEDr = (int*) &wxEVT_COMMAND_BUTTON_CLICKEDv;
|
||||
const int* wxEVENT_COMMAND_BUTTON_CLICKEDp = (int*) *wxEVT_COMMAND_BUTTON_CLICKEDp;
|
||||
const int* wxEVENT_COMMAND_BUTTON_CLICKEDp = (int*) *wxEVT_COMMAND_BUTTON_CLICKEDpp;
|
||||
char **languages1 = &langs[0];
|
||||
char **languages2 = (char **)&langs[0];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,10 +73,6 @@ public:
|
|||
|
||||
%include "std_vector.i"
|
||||
|
||||
#if defined(SWIGCSHARP)
|
||||
SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(Flow, Space::Flow)
|
||||
#endif
|
||||
|
||||
#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY)
|
||||
#define SWIG_GOOD_VECTOR
|
||||
%ignore std::vector<Space::Flow>::vector(size_type);
|
||||
|
|
|
|||
|
|
@ -1,36 +1,6 @@
|
|||
%module cpp_broken
|
||||
|
||||
|
||||
// bug #1060789
|
||||
%inline %{
|
||||
#define MASK(shift, size) (((1 << (size)) - 1) << (shift))
|
||||
#define SOME_MASK_DEF (80*MASK(8, 10))
|
||||
%}
|
||||
|
||||
// bug #1060079
|
||||
%inline %{
|
||||
#define FIELD(name, width) unsigned int name:width
|
||||
#define SOME_CONST 2
|
||||
#define NEXT_CONST (2 * SOME_CONST)
|
||||
|
||||
typedef struct {
|
||||
FIELD(a, SOME_CONST);
|
||||
FIELD(b, NEXT_CONST);
|
||||
} MyStruct_t;
|
||||
%}
|
||||
|
||||
%{
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
%}
|
||||
|
||||
// bug #994301
|
||||
%inline %{
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
%}
|
||||
|
||||
|
||||
// bug #940318
|
||||
%inline %{
|
||||
typedef enum {
|
||||
|
|
@ -40,36 +10,3 @@ eZero = 0
|
|||
%}
|
||||
|
||||
|
||||
// bug #754443
|
||||
|
||||
%inline %{
|
||||
#define MAG_STYLE_BORDER_OFFS 0
|
||||
#define MAG_STYLE_BORDER_BITS 3
|
||||
#define MAG_STYLE_BORDER_MASK (((1UL<<MAG_STYLE_BORDER_BITS)-1)<<MAG_STYLE_BORDER_OFFS)
|
||||
|
||||
/* these CANNOT be combined */
|
||||
#define MAG_STYLE_BORDER_NONE (1 << MAG_STYLE_BORDER_OFFS)
|
||||
#define MAG_STYLE_BORDER_STATIC (2 << MAG_STYLE_BORDER_OFFS)
|
||||
#define MAG_STYLE_BORDER_SIMPLE (3 << MAG_STYLE_BORDER_OFFS)
|
||||
#define MAG_STYLE_BORDER_RAISED (4 << MAG_STYLE_BORDER_OFFS)
|
||||
#define MAG_STYLE_BORDER_DOUBLE (5 << MAG_STYLE_BORDER_OFFS)
|
||||
#define MAG_STYLE_BORDER_DEFAULT MAG_STYLE_BORDER_SIMPLE
|
||||
|
||||
|
||||
#define MAG_STYLE_CAPTION_OFFS ( MAG_STYLE_BORDER_OFFS + MAG_STYLE_BORDER_BITS )
|
||||
#define MAG_STYLE_CAPTION_BITS 8
|
||||
#define MAG_STYLE_CAPTION_MASK (((1UL<<MAG_STYLE_CAPTION_BITS)-1)<<MAG_STYLE_CAPTION_OFFS)
|
||||
|
||||
/* these CAN be combined */
|
||||
#define MAG_STYLE_CAPTION_NONE ( 1 << ( 0 + MAG_STYLE_CAPTION_OFFS ))
|
||||
#define MAG_STYLE_CAPTION_PRESENT ( 1 << ( 1 + MAG_STYLE_CAPTION_OFFS ))
|
||||
#define MAG_STYLE_CAPTION_SYSMENU ( 1 << ( 2 + MAG_STYLE_CAPTION_OFFS ))
|
||||
#define MAG_STYLE_CAPTION_MINIMIZE ( 1 << ( 3 + MAG_STYLE_CAPTION_OFFS ))
|
||||
#define MAG_STYLE_CAPTION_MAXIMIZE ( 1 << ( 4 + MAG_STYLE_CAPTION_OFFS ))
|
||||
#define MAG_STYLE_CAPTION_RESIZE ( 1 << ( 5 + MAG_STYLE_CAPTION_OFFS ))
|
||||
#define MAG_STYLE_CAPTION_TINYHOR ( 1 << ( 6 + MAG_STYLE_CAPTION_OFFS ))
|
||||
#define MAG_STYLE_CAPTION_TINYVER ( 1 << ( 7 + MAG_STYLE_CAPTION_OFFS ))
|
||||
#define MAG_STYLE_CAPTION_DEFAULT ( MAG_STYLE_CAPTION_RESIZE + MAG_STYLE_CAPTION_MAXIMIZE + MAG_STYLE_CAPTION_MINIMIZE + MAG_STYLE_CAPTION_SYSMENU + MAG_STYLE_CAPTION_PRESENT )
|
||||
|
||||
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -15,24 +15,26 @@ CPP_TEST_CASES = \
|
|||
csharp_attributes \
|
||||
csharp_exceptions \
|
||||
csharp_features \
|
||||
csharp_lib_arrays \
|
||||
csharp_prepost \
|
||||
csharp_typemaps \
|
||||
enum_thorough_simple \
|
||||
enum_thorough_typesafe \
|
||||
exception_partial_info
|
||||
|
||||
CUSTOM_TEST_CASES = \
|
||||
csharp_lib_arrays \
|
||||
exception_partial_info \
|
||||
intermediary_classname
|
||||
|
||||
include $(srcdir)/../common.mk
|
||||
|
||||
# Overridden variables here
|
||||
SWIGOPT += -namespace $*Namespace $(SWIGOPTSPECIAL)
|
||||
SWIGOPT += -namespace $*Namespace
|
||||
INTERFACEDIR = ../../
|
||||
|
||||
CSHARPFLAGSSPECIAL =
|
||||
|
||||
# Custom tests - tests with additional commandline options
|
||||
intermediary_classname.cpptest: SWIGOPT += -dllimport intermediary_classname
|
||||
csharp_lib_arrays.cpptest: CSHARPFLAGSSPECIAL = -unsafe
|
||||
|
||||
# Rules for the different types of tests
|
||||
%.cpptest:
|
||||
$(setup)
|
||||
|
|
@ -49,12 +51,6 @@ CSHARPFLAGSSPECIAL =
|
|||
+(cd $* && $(swig_and_compile_multi_cpp))
|
||||
+$(run_testcase)
|
||||
|
||||
# Rules for custom tests
|
||||
intermediary_classname.customtest:
|
||||
$(MAKE) intermediary_classname.cpptest SWIGOPTSPECIAL="-dllimport intermediary_classname"
|
||||
csharp_lib_arrays.customtest:
|
||||
$(MAKE) csharp_lib_arrays.cpptest CSHARPFLAGSSPECIAL="-unsafe"
|
||||
|
||||
# Makes a directory for the testcase if it does not exist
|
||||
setup = \
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
|
||||
|
|
@ -63,31 +59,31 @@ setup = \
|
|||
echo "$(ACTION)ing testcase $* under $(LANGUAGE)" ; \
|
||||
fi; \
|
||||
if [ ! -d $* ]; then \
|
||||
mkdir $*; \
|
||||
fi;
|
||||
mkdir $*; \
|
||||
fi
|
||||
|
||||
# Compiles C# files then runs the testcase. A testcase is only run if
|
||||
# a file is found which has _runme.cs appended after the testcase name.
|
||||
# Note C# uses LD_LIBRARY_PATH under Unix, PATH under Cygwin/Windows and SHLIB_PATH on HPUX.
|
||||
run_testcase = \
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then ( \
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
|
||||
$(MAKE) -f $*/$(top_builddir)/$(EXAMPLES)/Makefile \
|
||||
CSHARPFLAGS='-nologo $(CSHARPFLAGSSPECIAL) -out:$*_runme.exe' \
|
||||
CSHARPSRCS='`$(CSHARPCYGPATH_W) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX)` \
|
||||
$*$(CSHARPPATHSEPARATOR)*.cs' csharp_compile && \
|
||||
env LD_LIBRARY_PATH="$*:$$LD_LIBRARY_PATH" PATH="$*:$$PATH" SHLIB_PATH="$*:$$SHLIB_PATH" $(RUNTOOL) $(INTERPRETER) $*_runme.exe; ) \
|
||||
else ( \
|
||||
env LD_LIBRARY_PATH="$*:$$LD_LIBRARY_PATH" PATH="$*:$$PATH" SHLIB_PATH="$*:$$SHLIB_PATH" $(RUNTOOL) $(INTERPRETER) $*_runme.exe; \
|
||||
else \
|
||||
cd $* && \
|
||||
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
|
||||
CSHARPFLAGS='-nologo $(CSHARPFLAGSSPECIAL) -t:module -out:$*.netmodule' \
|
||||
CSHARPSRCS='*.cs' csharp_compile; ); \
|
||||
fi;
|
||||
CSHARPSRCS='*.cs' csharp_compile && cd .. ; \
|
||||
fi
|
||||
|
||||
# Clean: remove testcase directories
|
||||
%.clean:
|
||||
@if [ -d $* ]; then \
|
||||
rm -rf $*; \
|
||||
fi;
|
||||
rm -rf $*; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
@rm -f *.exe *.exe.mdb
|
||||
|
|
|
|||
66
Examples/test-suite/csharp/catches_runme.cs
Normal file
66
Examples/test-suite/csharp/catches_runme.cs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using catchesNamespace;
|
||||
|
||||
public class runme {
|
||||
static void Main() {
|
||||
// test_catches()
|
||||
try {
|
||||
catches.test_catches(1);
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "C++ int exception thrown, value: 1")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
try {
|
||||
catches.test_catches(2);
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "two")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
try {
|
||||
catches.test_catches(3);
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "C++ ThreeException const & exception thrown")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
// test_exception_specification()
|
||||
try {
|
||||
catches.test_exception_specification(1);
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "C++ int exception thrown, value: 1")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
try {
|
||||
catches.test_exception_specification(2);
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "unknown exception")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
try {
|
||||
catches.test_exception_specification(3);
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "unknown exception")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
// test_catches_all()
|
||||
try {
|
||||
catches.test_catches_all(1);
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "unknown exception")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -120,15 +120,26 @@ public class char_strings_runme {
|
|||
|
||||
// char *& tests
|
||||
for (i=0; i<count; i++) {
|
||||
String str = char_strings.GetConstCharPointerRef();
|
||||
String str = char_strings.GetCharPointerRef();
|
||||
if (str != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test char pointer ref get failed, iteration " + i);
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!char_strings.SetConstCharPointerRef(OTHERLAND_MSG + i, i))
|
||||
if (!char_strings.SetCharPointerRef(OTHERLAND_MSG + i, i))
|
||||
throw new Exception("Test char pointer ref set failed, iteration " + i);
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
String str = char_strings.GetConstCharPointerRef();
|
||||
if (str != CPLUSPLUS_MSG)
|
||||
throw new Exception("Test const char pointer ref get failed, iteration " + i);
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (!char_strings.SetConstCharPointerRef(OTHERLAND_MSG + i, i))
|
||||
throw new Exception("Test const char pointer ref set failed, iteration " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
using csharp_attributesNamespace;
|
||||
|
||||
public class runme
|
||||
|
|
@ -171,6 +172,24 @@ public class runme
|
|||
if (Attribute.GetCustomAttribute(member, typeof(Eurostar2Attribute)) == null)
|
||||
throw new Exception("No attribute for " + member.Name);
|
||||
}
|
||||
// Enum value attributes
|
||||
Type walesType = typeof(MoreStations.Wales);
|
||||
{
|
||||
MemberInfo member = (MemberInfo)walesType.GetMember("Cardiff")[0];
|
||||
DescriptionAttribute attribute = (DescriptionAttribute)Attribute.GetCustomAttribute(member, typeof(System.ComponentModel.DescriptionAttribute));
|
||||
if (attribute == null)
|
||||
throw new Exception("No attribute for " + member.Name);
|
||||
if (attribute.Description != "Cardiff city station")
|
||||
throw new Exception("Incorrect attribute value for " + member.Name);
|
||||
}
|
||||
{
|
||||
MemberInfo member = (MemberInfo)walesType.GetMember("Swansea")[0];
|
||||
DescriptionAttribute attribute = (DescriptionAttribute)Attribute.GetCustomAttribute(member, typeof(System.ComponentModel.DescriptionAttribute));
|
||||
if (attribute == null)
|
||||
throw new Exception("No attribute for " + member.Name);
|
||||
if (attribute.Description != "Swansea city station")
|
||||
throw new Exception("Incorrect attribute value for " + member.Name);
|
||||
}
|
||||
// Enum csattribute typemap
|
||||
{
|
||||
Type cymrutype = typeof(Cymru);
|
||||
|
|
@ -179,6 +198,8 @@ public class runme
|
|||
if (tgv == null)
|
||||
throw new Exception("No attribute for Cymru");
|
||||
}
|
||||
|
||||
// No runtime test for directorinattributes and directoroutattributes
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -237,3 +258,9 @@ public class ThreadSafeAttribute : Attribute {
|
|||
public ThreadSafeAttribute() {}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
|
||||
public class DirectorIntegerOutAttribute : Attribute {}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
|
||||
public class DirectorIntegerInAttribute : Attribute {}
|
||||
|
||||
|
|
|
|||
|
|
@ -358,12 +358,51 @@ public class runme {
|
|||
i.MemberInstance = Instances.memberinstance3;
|
||||
if (i.MemberInstance != Instances.memberinstance3) throw new Exception("MemberInstance 1 failed");
|
||||
}
|
||||
// ignore enum item tests start
|
||||
{
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_zero) != 0) throw new Exception("ignoreATest 0 failed");
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_three) != 3) throw new Exception("ignoreATest 3 failed");
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_ten) != 10) throw new Exception("ignoreATest 10 failed");
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_eleven) != 11) throw new Exception("ignoreATest 11 failed");
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirteen) != 13) throw new Exception("ignoreATest 13 failed");
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_fourteen) != 14) throw new Exception("ignoreATest 14 failed");
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_twenty) != 20) throw new Exception("ignoreATest 20 failed");
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty) != 30) throw new Exception("ignoreATest 30 failed");
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_two) != 32) throw new Exception("ignoreATest 32 failed");
|
||||
if ((int)enum_thorough.ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_three) != 33) throw new Exception("ignoreATest 33 failed");
|
||||
}
|
||||
{
|
||||
if ((int)enum_thorough.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_eleven) != 11) throw new Exception("ignoreBTest 11 failed");
|
||||
if ((int)enum_thorough.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_twelve) != 12) throw new Exception("ignoreBTest 12 failed");
|
||||
if ((int)enum_thorough.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_one) != 31) throw new Exception("ignoreBTest 31 failed");
|
||||
if ((int)enum_thorough.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_two) != 32) throw new Exception("ignoreBTest 32 failed");
|
||||
if ((int)enum_thorough.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_one) != 41) throw new Exception("ignoreBTest 41 failed");
|
||||
if ((int)enum_thorough.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_two) != 42) throw new Exception("ignoreBTest 42 failed");
|
||||
}
|
||||
{
|
||||
if ((int)enum_thorough.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_ten) != 10) throw new Exception("ignoreCTest 10 failed");
|
||||
if ((int)enum_thorough.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_twelve) != 12) throw new Exception("ignoreCTest 12 failed");
|
||||
if ((int)enum_thorough.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty) != 30) throw new Exception("ignoreCTest 30 failed");
|
||||
if ((int)enum_thorough.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty_two) != 32) throw new Exception("ignoreCTest 32 failed");
|
||||
if ((int)enum_thorough.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty) != 40) throw new Exception("ignoreCTest 40 failed");
|
||||
if ((int)enum_thorough.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty_two) != 42) throw new Exception("ignoreCTest 42 failed");
|
||||
}
|
||||
{
|
||||
if ((int)enum_thorough.ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_one) != 21) throw new Exception("ignoreDTest 21 failed");
|
||||
if ((int)enum_thorough.ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_two) != 22) throw new Exception("ignoreDTest 22 failed");
|
||||
}
|
||||
{
|
||||
if ((int)enum_thorough.ignoreETest(IgnoreTest.IgnoreE.ignoreE_zero) != 0) throw new Exception("ignoreETest 0 failed");
|
||||
if ((int)enum_thorough.ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_one) != 21) throw new Exception("ignoreETest 21 failed");
|
||||
if ((int)enum_thorough.ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_two) != 22) throw new Exception("ignoreETest 22 failed");
|
||||
}
|
||||
// ignore enum item tests end
|
||||
{
|
||||
if ((int)enum_thorough.repeatTest(repeat.one) != 1) throw new Exception("repeatTest 1 failed");
|
||||
if ((int)enum_thorough.repeatTest(repeat.initial) != 1) throw new Exception("repeatTest 2 failed");
|
||||
if ((int)enum_thorough.repeatTest(repeat.two) != 2) throw new Exception("repeatTest 3 failed");
|
||||
if ((int)enum_thorough.repeatTest(repeat.three) != 3) throw new Exception("repeatTest 4 failed");
|
||||
if ((int)enum_thorough.repeatTest(repeat.last) != 3) throw new Exception("repeatTest 5 failed");
|
||||
if ((int)enum_thorough.repeatTest(repeat.llast) != 3) throw new Exception("repeatTest 5 failed");
|
||||
if ((int)enum_thorough.repeatTest(repeat.end) != 3) throw new Exception("repeatTest 6 failed");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -358,12 +358,51 @@ public class runme {
|
|||
i.MemberInstance = Instances.memberinstance3;
|
||||
if (i.MemberInstance != Instances.memberinstance3) throw new Exception("MemberInstance 1 failed");
|
||||
}
|
||||
// ignore enum item tests start
|
||||
{
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_zero) != 0) throw new Exception("ignoreATest 0 failed");
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_three) != 3) throw new Exception("ignoreATest 3 failed");
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_ten) != 10) throw new Exception("ignoreATest 10 failed");
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_eleven) != 11) throw new Exception("ignoreATest 11 failed");
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_thirteen) != 13) throw new Exception("ignoreATest 13 failed");
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_fourteen) != 14) throw new Exception("ignoreATest 14 failed");
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_twenty) != 20) throw new Exception("ignoreATest 20 failed");
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_thirty) != 30) throw new Exception("ignoreATest 30 failed");
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_thirty_two) != 32) throw new Exception("ignoreATest 32 failed");
|
||||
if (enum_thorough_simple.ignoreATest(IgnoreTest.ignoreA_thirty_three) != 33) throw new Exception("ignoreATest 33 failed");
|
||||
}
|
||||
{
|
||||
if (enum_thorough_simple.ignoreBTest(IgnoreTest.ignoreB_eleven) != 11) throw new Exception("ignoreBTest 11 failed");
|
||||
if (enum_thorough_simple.ignoreBTest(IgnoreTest.ignoreB_twelve) != 12) throw new Exception("ignoreBTest 12 failed");
|
||||
if (enum_thorough_simple.ignoreBTest(IgnoreTest.ignoreB_thirty_one) != 31) throw new Exception("ignoreBTest 31 failed");
|
||||
if (enum_thorough_simple.ignoreBTest(IgnoreTest.ignoreB_thirty_two) != 32) throw new Exception("ignoreBTest 32 failed");
|
||||
if (enum_thorough_simple.ignoreBTest(IgnoreTest.ignoreB_forty_one) != 41) throw new Exception("ignoreBTest 41 failed");
|
||||
if (enum_thorough_simple.ignoreBTest(IgnoreTest.ignoreB_forty_two) != 42) throw new Exception("ignoreBTest 42 failed");
|
||||
}
|
||||
{
|
||||
if (enum_thorough_simple.ignoreCTest(IgnoreTest.ignoreC_ten) != 10) throw new Exception("ignoreCTest 10 failed");
|
||||
if (enum_thorough_simple.ignoreCTest(IgnoreTest.ignoreC_twelve) != 12) throw new Exception("ignoreCTest 12 failed");
|
||||
if (enum_thorough_simple.ignoreCTest(IgnoreTest.ignoreC_thirty) != 30) throw new Exception("ignoreCTest 30 failed");
|
||||
if (enum_thorough_simple.ignoreCTest(IgnoreTest.ignoreC_thirty_two) != 32) throw new Exception("ignoreCTest 32 failed");
|
||||
if (enum_thorough_simple.ignoreCTest(IgnoreTest.ignoreC_forty) != 40) throw new Exception("ignoreCTest 40 failed");
|
||||
if (enum_thorough_simple.ignoreCTest(IgnoreTest.ignoreC_forty_two) != 42) throw new Exception("ignoreCTest 42 failed");
|
||||
}
|
||||
{
|
||||
if (enum_thorough_simple.ignoreDTest(IgnoreTest.ignoreD_twenty_one) != 21) throw new Exception("ignoreDTest 21 failed");
|
||||
if (enum_thorough_simple.ignoreDTest(IgnoreTest.ignoreD_twenty_two) != 22) throw new Exception("ignoreDTest 22 failed");
|
||||
}
|
||||
{
|
||||
if (enum_thorough_simple.ignoreETest(IgnoreTest.ignoreE_zero) != 0) throw new Exception("ignoreETest 0 failed");
|
||||
if (enum_thorough_simple.ignoreETest(IgnoreTest.ignoreE_twenty_one) != 21) throw new Exception("ignoreETest 21 failed");
|
||||
if (enum_thorough_simple.ignoreETest(IgnoreTest.ignoreE_twenty_two) != 22) throw new Exception("ignoreETest 22 failed");
|
||||
}
|
||||
// ignore enum item tests end
|
||||
{
|
||||
if (enum_thorough_simple.repeatTest(enum_thorough_simple.one) != 1) throw new Exception("repeatTest 1 failed");
|
||||
if (enum_thorough_simple.repeatTest(enum_thorough_simple.initial) != 1) throw new Exception("repeatTest 2 failed");
|
||||
if (enum_thorough_simple.repeatTest(enum_thorough_simple.two) != 2) throw new Exception("repeatTest 3 failed");
|
||||
if (enum_thorough_simple.repeatTest(enum_thorough_simple.three) != 3) throw new Exception("repeatTest 4 failed");
|
||||
if (enum_thorough_simple.repeatTest(enum_thorough_simple.last) != 3) throw new Exception("repeatTest 5 failed");
|
||||
if (enum_thorough_simple.repeatTest(enum_thorough_simple.llast) != 3) throw new Exception("repeatTest 5 failed");
|
||||
if (enum_thorough_simple.repeatTest(enum_thorough_simple.end) != 3) throw new Exception("repeatTest 6 failed");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -358,12 +358,51 @@ public class runme {
|
|||
i.MemberInstance = Instances.memberinstance3;
|
||||
if (i.MemberInstance != Instances.memberinstance3) throw new Exception("MemberInstance 1 failed");
|
||||
}
|
||||
// ignore enum item tests start
|
||||
{
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_zero).swigValue != 0) throw new Exception("ignoreATest 0 failed");
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_three).swigValue != 3) throw new Exception("ignoreATest 3 failed");
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_ten).swigValue != 10) throw new Exception("ignoreATest 10 failed");
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_eleven).swigValue != 11) throw new Exception("ignoreATest 11 failed");
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirteen).swigValue != 13) throw new Exception("ignoreATest 13 failed");
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_fourteen).swigValue != 14) throw new Exception("ignoreATest 14 failed");
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_twenty).swigValue != 20) throw new Exception("ignoreATest 20 failed");
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty).swigValue != 30) throw new Exception("ignoreATest 30 failed");
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_two).swigValue != 32) throw new Exception("ignoreATest 32 failed");
|
||||
if (enum_thorough_typesafe.ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_three).swigValue != 33) throw new Exception("ignoreATest 33 failed");
|
||||
}
|
||||
{
|
||||
if (enum_thorough_typesafe.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_eleven).swigValue != 11) throw new Exception("ignoreBTest 11 failed");
|
||||
if (enum_thorough_typesafe.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_twelve).swigValue != 12) throw new Exception("ignoreBTest 12 failed");
|
||||
if (enum_thorough_typesafe.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_one).swigValue != 31) throw new Exception("ignoreBTest 31 failed");
|
||||
if (enum_thorough_typesafe.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_two).swigValue != 32) throw new Exception("ignoreBTest 32 failed");
|
||||
if (enum_thorough_typesafe.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_one).swigValue != 41) throw new Exception("ignoreBTest 41 failed");
|
||||
if (enum_thorough_typesafe.ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_two).swigValue != 42) throw new Exception("ignoreBTest 42 failed");
|
||||
}
|
||||
{
|
||||
if (enum_thorough_typesafe.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_ten).swigValue != 10) throw new Exception("ignoreCTest 10 failed");
|
||||
if (enum_thorough_typesafe.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_twelve).swigValue != 12) throw new Exception("ignoreCTest 12 failed");
|
||||
if (enum_thorough_typesafe.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty).swigValue != 30) throw new Exception("ignoreCTest 30 failed");
|
||||
if (enum_thorough_typesafe.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty_two).swigValue != 32) throw new Exception("ignoreCTest 32 failed");
|
||||
if (enum_thorough_typesafe.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty).swigValue != 40) throw new Exception("ignoreCTest 40 failed");
|
||||
if (enum_thorough_typesafe.ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty_two).swigValue != 42) throw new Exception("ignoreCTest 42 failed");
|
||||
}
|
||||
{
|
||||
if (enum_thorough_typesafe.ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_one).swigValue != 21) throw new Exception("ignoreDTest 21 failed");
|
||||
if (enum_thorough_typesafe.ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_two).swigValue != 22) throw new Exception("ignoreDTest 22 failed");
|
||||
}
|
||||
{
|
||||
if (enum_thorough_typesafe.ignoreETest(IgnoreTest.IgnoreE.ignoreE_zero).swigValue != 0) throw new Exception("ignoreETest 0 failed");
|
||||
if (enum_thorough_typesafe.ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_one).swigValue != 21) throw new Exception("ignoreETest 21 failed");
|
||||
if (enum_thorough_typesafe.ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_two).swigValue != 22) throw new Exception("ignoreETest 22 failed");
|
||||
}
|
||||
// ignore enum item tests end
|
||||
{
|
||||
if (enum_thorough_typesafe.repeatTest(repeat.one).swigValue != 1) throw new Exception("repeatTest 1 failed");
|
||||
if (enum_thorough_typesafe.repeatTest(repeat.initial).swigValue != 1) throw new Exception("repeatTest 2 failed");
|
||||
if (enum_thorough_typesafe.repeatTest(repeat.two).swigValue != 2) throw new Exception("repeatTest 3 failed");
|
||||
if (enum_thorough_typesafe.repeatTest(repeat.three).swigValue != 3) throw new Exception("repeatTest 4 failed");
|
||||
if (enum_thorough_typesafe.repeatTest(repeat.last).swigValue != 3) throw new Exception("repeatTest 5 failed");
|
||||
if (enum_thorough_typesafe.repeatTest(repeat.llast).swigValue != 3) throw new Exception("repeatTest 5 failed");
|
||||
if (enum_thorough_typesafe.repeatTest(repeat.end).swigValue != 3) throw new Exception("repeatTest 6 failed");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
48
Examples/test-suite/csharp/exception_order_runme.cs
Normal file
48
Examples/test-suite/csharp/exception_order_runme.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using exception_orderNamespace;
|
||||
|
||||
public class runme {
|
||||
static void Main() {
|
||||
A a = new A();
|
||||
|
||||
try {
|
||||
a.foo();
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "C++ E1 exception thrown")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
try {
|
||||
a.bar();
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "C++ E2 exception thrown")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
try {
|
||||
a.foobar();
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "postcatch unknown")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
try {
|
||||
a.barfoo(1);
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "C++ E1 exception thrown")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
|
||||
try {
|
||||
a.barfoo(2);
|
||||
throw new Exception("missed exception");
|
||||
} catch (ApplicationException e) {
|
||||
if (e.Message != "C++ E2 * exception thrown")
|
||||
throw new ApplicationException("bad exception order: " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -164,7 +164,7 @@ public class li_std_map_runme {
|
|||
if (keyStringified != " 1 2 3 4 5")
|
||||
throw new Exception("Wrapped method stringifyKeys test failed. Got " + keyStringified);
|
||||
|
||||
// Test a map with a new specialized type (Struct)
|
||||
// Test a map with a new complex type (Struct)
|
||||
{
|
||||
IntStructMap ismap = new IntStructMap();
|
||||
for (int i = 0; i < 10; i++)
|
||||
|
|
@ -173,12 +173,12 @@ public class li_std_map_runme {
|
|||
}
|
||||
|
||||
if (ismap.Count != 10)
|
||||
throw new Exception("Count test on specialized map failed");
|
||||
throw new Exception("Count test on complex type map failed");
|
||||
|
||||
foreach (KeyValuePair<int, Struct> p in ismap)
|
||||
{
|
||||
if ((p.Key * 10.1) != p.Value.num)
|
||||
throw new Exception("Iteration test on specialized map failed for index " + p.Key);
|
||||
throw new Exception("Iteration test on complex type map failed for index " + p.Key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,12 +191,12 @@ public class li_std_map_runme {
|
|||
}
|
||||
|
||||
if (ispmap.Count != 10)
|
||||
throw new Exception("Count test on specialized pointer map failed");
|
||||
throw new Exception("Count test on complex type pointer map failed");
|
||||
|
||||
foreach (KeyValuePair<int, Struct> p in ispmap)
|
||||
{
|
||||
if ((p.Key * 10.1) != p.Value.num)
|
||||
throw new Exception("Iteration test on specialized pointer map failed for index " + p.Key);
|
||||
throw new Exception("Iteration test on complex type pointer map failed for index " + p.Key);
|
||||
}
|
||||
}
|
||||
{
|
||||
|
|
@ -207,29 +207,29 @@ public class li_std_map_runme {
|
|||
}
|
||||
|
||||
if (iscpmap.Count != 10)
|
||||
throw new Exception("Count test on specialized const pointer map failed");
|
||||
throw new Exception("Count test on complex type const pointer map failed");
|
||||
|
||||
foreach (KeyValuePair<int, Struct> p in iscpmap)
|
||||
{
|
||||
if ((p.Key * 10.1) != p.Value.num)
|
||||
throw new Exception("Iteration test on specialized const pointer map failed for index " + p.Key);
|
||||
throw new Exception("Iteration test on complex type const pointer map failed for index " + p.Key);
|
||||
}
|
||||
}
|
||||
|
||||
// Test non-specialized map
|
||||
// Test complex type as key (Struct)
|
||||
{
|
||||
StructIntMap limap = new StructIntMap();
|
||||
Struct s7 = new Struct(7);
|
||||
Struct s8 = new Struct(8);
|
||||
limap.setitem(s7 , 8);
|
||||
if (limap.getitem(s7) != 8)
|
||||
throw new Exception("Assignment test on non-specialized map failed");
|
||||
limap[s7] = 8;
|
||||
if (limap[s7] != 8)
|
||||
throw new Exception("Assignment test on complex key map failed");
|
||||
|
||||
if (!limap.ContainsKey(s7))
|
||||
throw new Exception("Key test (1) on non-specialized map failed");
|
||||
throw new Exception("Key test (1) on complex key map failed");
|
||||
|
||||
if (limap.ContainsKey(s8))
|
||||
throw new Exception("Key test (2) on non-specialized map failed");
|
||||
throw new Exception("Key test (2) on complex key map failed");
|
||||
}
|
||||
|
||||
// All done
|
||||
|
|
|
|||
|
|
@ -158,7 +158,8 @@ public class li_std_vector_runme {
|
|||
} catch (ArgumentNullException) {
|
||||
}
|
||||
{
|
||||
myDoubleVector = new DoubleVector() { 123.4, 567.8, 901.2 };
|
||||
// Collection initializer test, requires C# 3.0
|
||||
// myDoubleVector = new DoubleVector() { 123.4, 567.8, 901.2 };
|
||||
}
|
||||
|
||||
// IndexOf() test
|
||||
|
|
@ -542,8 +543,8 @@ public class li_std_vector_runme {
|
|||
|
||||
// Dispose()
|
||||
{
|
||||
using (StructVector vs = new StructVector() { new Struct(0.0), new Struct(11.1) } )
|
||||
using (DoubleVector vd = new DoubleVector() { 0.0, 11.1 } ) {
|
||||
using (StructVector vs = new StructVector( new Struct[] { new Struct(0.0), new Struct(11.1) } ) )
|
||||
using (DoubleVector vd = new DoubleVector( new double[] { 0.0, 11.1 } ) ) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ public class runme
|
|||
{
|
||||
int f = overload_template.foo();
|
||||
|
||||
f += overload_template.max(3,4);
|
||||
double b = overload_template.max(3.4,5.2);
|
||||
f += overload_template.maximum(3,4);
|
||||
double b = overload_template.maximum(3.4,5.2);
|
||||
b++; // warning suppression
|
||||
|
||||
// mix 1
|
||||
|
|
|
|||
70
Examples/test-suite/csharp/preproc_constants_c_runme.cs
Normal file
70
Examples/test-suite/csharp/preproc_constants_c_runme.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using preproc_constants_cNamespace;
|
||||
|
||||
// Same as preproc_constants_c.i testcase, but bool types are int instead
|
||||
public class runme {
|
||||
static void Main() {
|
||||
assert( typeof(int) == preproc_constants_c.CONST_INT1.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.CONST_INT2.GetType() );
|
||||
assert( typeof(uint) == preproc_constants_c.CONST_UINT1.GetType() );
|
||||
assert( typeof(uint) == preproc_constants_c.CONST_UINT2.GetType() );
|
||||
assert( typeof(uint) == preproc_constants_c.CONST_UINT3.GetType() );
|
||||
assert( typeof(uint) == preproc_constants_c.CONST_UINT4.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.CONST_LONG1.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.CONST_LONG2.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.CONST_LONG3.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.CONST_LONG4.GetType() );
|
||||
assert( typeof(long) == preproc_constants_c.CONST_LLONG1.GetType() );
|
||||
assert( typeof(long) == preproc_constants_c.CONST_LLONG2.GetType() );
|
||||
assert( typeof(long) == preproc_constants_c.CONST_LLONG3.GetType() );
|
||||
assert( typeof(long) == preproc_constants_c.CONST_LLONG4.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants_c.CONST_ULLONG1.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants_c.CONST_ULLONG2.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants_c.CONST_ULLONG3.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants_c.CONST_ULLONG4.GetType() );
|
||||
assert( typeof(double) == preproc_constants_c.CONST_DOUBLE1.GetType() );
|
||||
assert( typeof(double) == preproc_constants_c.CONST_DOUBLE2.GetType() );
|
||||
assert( typeof(double) == preproc_constants_c.CONST_DOUBLE3.GetType() );
|
||||
assert( typeof(double) == preproc_constants_c.CONST_DOUBLE4.GetType() );
|
||||
assert( typeof(double) == preproc_constants_c.CONST_DOUBLE5.GetType() );
|
||||
assert( typeof(double) == preproc_constants_c.CONST_DOUBLE6.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.CONST_BOOL1.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.CONST_BOOL2.GetType() );
|
||||
assert( typeof(char) == preproc_constants_c.CONST_CHAR.GetType() );
|
||||
assert( typeof(string) == preproc_constants_c.CONST_STRING1.GetType() );
|
||||
assert( typeof(string) == preproc_constants_c.CONST_STRING2.GetType() );
|
||||
|
||||
assert( typeof(int) == preproc_constants_c.INT_AND_BOOL.GetType() );
|
||||
// assert( typeof(int) == preproc_constants_c.INT_AND_CHAR.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.INT_AND_INT.GetType() );
|
||||
assert( typeof(uint) == preproc_constants_c.INT_AND_UINT.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.INT_AND_LONG.GetType() );
|
||||
assert( typeof(uint) == preproc_constants_c.INT_AND_ULONG.GetType() );
|
||||
assert( typeof(long) == preproc_constants_c.INT_AND_LLONG.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants_c.INT_AND_ULLONG.GetType() );
|
||||
assert( typeof(int ) == preproc_constants_c.BOOL_AND_BOOL.GetType() );
|
||||
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_MULTIPLY.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_DIVIDE.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_PLUS.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_MINUS.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_LSHIFT.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_RSHIFT.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_LTE.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_GTE.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_INEQUALITY.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_EQUALITY.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_AND.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_XOR.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_OR.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_LAND.GetType() );
|
||||
assert( typeof(int) == preproc_constants_c.EXPR_LOR.GetType() );
|
||||
assert( typeof(double) == preproc_constants_c.EXPR_CONDITIONAL.GetType() );
|
||||
|
||||
}
|
||||
static void assert(bool assertion) {
|
||||
if (!assertion)
|
||||
throw new ApplicationException("test failed");
|
||||
}
|
||||
}
|
||||
69
Examples/test-suite/csharp/preproc_constants_runme.cs
Normal file
69
Examples/test-suite/csharp/preproc_constants_runme.cs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using preproc_constantsNamespace;
|
||||
|
||||
public class runme {
|
||||
static void Main() {
|
||||
assert( typeof(int) == preproc_constants.CONST_INT1.GetType() );
|
||||
assert( typeof(int) == preproc_constants.CONST_INT2.GetType() );
|
||||
assert( typeof(uint) == preproc_constants.CONST_UINT1.GetType() );
|
||||
assert( typeof(uint) == preproc_constants.CONST_UINT2.GetType() );
|
||||
assert( typeof(uint) == preproc_constants.CONST_UINT3.GetType() );
|
||||
assert( typeof(uint) == preproc_constants.CONST_UINT4.GetType() );
|
||||
assert( typeof(int) == preproc_constants.CONST_LONG1.GetType() );
|
||||
assert( typeof(int) == preproc_constants.CONST_LONG2.GetType() );
|
||||
assert( typeof(int) == preproc_constants.CONST_LONG3.GetType() );
|
||||
assert( typeof(int) == preproc_constants.CONST_LONG4.GetType() );
|
||||
assert( typeof(long) == preproc_constants.CONST_LLONG1.GetType() );
|
||||
assert( typeof(long) == preproc_constants.CONST_LLONG2.GetType() );
|
||||
assert( typeof(long) == preproc_constants.CONST_LLONG3.GetType() );
|
||||
assert( typeof(long) == preproc_constants.CONST_LLONG4.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants.CONST_ULLONG1.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants.CONST_ULLONG2.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants.CONST_ULLONG3.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants.CONST_ULLONG4.GetType() );
|
||||
assert( typeof(double) == preproc_constants.CONST_DOUBLE1.GetType() );
|
||||
assert( typeof(double) == preproc_constants.CONST_DOUBLE2.GetType() );
|
||||
assert( typeof(double) == preproc_constants.CONST_DOUBLE3.GetType() );
|
||||
assert( typeof(double) == preproc_constants.CONST_DOUBLE4.GetType() );
|
||||
assert( typeof(double) == preproc_constants.CONST_DOUBLE5.GetType() );
|
||||
assert( typeof(double) == preproc_constants.CONST_DOUBLE6.GetType() );
|
||||
assert( typeof(bool) == preproc_constants.CONST_BOOL1.GetType() );
|
||||
assert( typeof(bool) == preproc_constants.CONST_BOOL2.GetType() );
|
||||
assert( typeof(char) == preproc_constants.CONST_CHAR.GetType() );
|
||||
assert( typeof(string) == preproc_constants.CONST_STRING1.GetType() );
|
||||
assert( typeof(string) == preproc_constants.CONST_STRING2.GetType() );
|
||||
|
||||
assert( typeof(int) == preproc_constants.INT_AND_BOOL.GetType() );
|
||||
// assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() );
|
||||
assert( typeof(int) == preproc_constants.INT_AND_INT.GetType() );
|
||||
assert( typeof(uint) == preproc_constants.INT_AND_UINT.GetType() );
|
||||
assert( typeof(int) == preproc_constants.INT_AND_LONG.GetType() );
|
||||
assert( typeof(uint) == preproc_constants.INT_AND_ULONG.GetType() );
|
||||
assert( typeof(long) == preproc_constants.INT_AND_LLONG.GetType() );
|
||||
assert( typeof(ulong) == preproc_constants.INT_AND_ULLONG.GetType() );
|
||||
assert( typeof(int ) == preproc_constants.BOOL_AND_BOOL.GetType() );
|
||||
|
||||
assert( typeof(int) == preproc_constants.EXPR_MULTIPLY.GetType() );
|
||||
assert( typeof(int) == preproc_constants.EXPR_DIVIDE.GetType() );
|
||||
assert( typeof(int) == preproc_constants.EXPR_PLUS.GetType() );
|
||||
assert( typeof(int) == preproc_constants.EXPR_MINUS.GetType() );
|
||||
assert( typeof(int) == preproc_constants.EXPR_LSHIFT.GetType() );
|
||||
assert( typeof(int) == preproc_constants.EXPR_RSHIFT.GetType() );
|
||||
assert( typeof(bool) == preproc_constants.EXPR_LTE.GetType() );
|
||||
assert( typeof(bool) == preproc_constants.EXPR_GTE.GetType() );
|
||||
assert( typeof(bool) == preproc_constants.EXPR_INEQUALITY.GetType() );
|
||||
assert( typeof(bool) == preproc_constants.EXPR_EQUALITY.GetType() );
|
||||
assert( typeof(int) == preproc_constants.EXPR_AND.GetType() );
|
||||
assert( typeof(int) == preproc_constants.EXPR_XOR.GetType() );
|
||||
assert( typeof(int) == preproc_constants.EXPR_OR.GetType() );
|
||||
assert( typeof(bool) == preproc_constants.EXPR_LAND.GetType() );
|
||||
assert( typeof(bool) == preproc_constants.EXPR_LOR.GetType() );
|
||||
assert( typeof(double) == preproc_constants.EXPR_CONDITIONAL.GetType() );
|
||||
|
||||
}
|
||||
static void assert(bool assertion) {
|
||||
if (!assertion)
|
||||
throw new ApplicationException("test failed");
|
||||
}
|
||||
}
|
||||
22
Examples/test-suite/csharp/special_variable_macros_runme.cs
Normal file
22
Examples/test-suite/csharp/special_variable_macros_runme.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using special_variable_macrosNamespace;
|
||||
|
||||
public class runme {
|
||||
static void Main() {
|
||||
Name name = new Name();
|
||||
if (special_variable_macros.testFred(name) != "none")
|
||||
throw new Exception("test failed");
|
||||
if (special_variable_macros.testJack(name) != "$specialname")
|
||||
throw new Exception("test failed");
|
||||
if (special_variable_macros.testJill(name) != "jilly")
|
||||
throw new Exception("test failed");
|
||||
if (special_variable_macros.testMary(name) != "SWIGTYPE_p_NameWrap")
|
||||
throw new Exception("test failed");
|
||||
if (special_variable_macros.testJim(name) != "multiname num")
|
||||
throw new Exception("test failed");
|
||||
if (special_variable_macros.testJohn(new PairIntBool(10, false)) != 123)
|
||||
throw new Exception("test failed");
|
||||
NewName newName = NewName.factory("factoryname");
|
||||
name = newName.getStoredName();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
%module csharp_attributes
|
||||
%module(directors="1") csharp_attributes
|
||||
|
||||
// Test the inattributes and outattributes typemaps
|
||||
%typemap(cstype, outattributes="[IntOut]", inattributes="[IntIn]") int "int"
|
||||
|
|
@ -15,6 +15,8 @@ public:
|
|||
int GlobalFunction(int myInt) { return myInt; }
|
||||
%}
|
||||
|
||||
//%include "enumsimple.swg"
|
||||
//%include "enumtypesafe.swg"
|
||||
|
||||
// Test the attributes feature
|
||||
%csattributes MoreStations::MoreStations() "[InterCity1]"
|
||||
|
|
@ -25,6 +27,8 @@ int GlobalFunction(int myInt) { return myInt; }
|
|||
%csattributes Wales "[InterCity6]"
|
||||
%csattributes Paddington() "[InterCity7]"
|
||||
%csattributes DidcotParkway "[InterCity8]"
|
||||
%csattributes MoreStations::Cardiff "[System.ComponentModel.Description(\"Cardiff city station\")]"
|
||||
%csattributes Swansea "[System.ComponentModel.Description(\"Swansea city station\")]"
|
||||
|
||||
%typemap(csattributes) MoreStations "[Eurostar1]"
|
||||
%typemap(csattributes) MoreStations::Wales "[Eurostar2]"
|
||||
|
|
@ -46,3 +50,13 @@ enum Cymru { Llanelli };
|
|||
double MoreStations::WestonSuperMare = 0.0;
|
||||
%}
|
||||
|
||||
// Test directorinattributes and directoroutattributes
|
||||
%typemap(imtype, directoroutattributes="[DirectorIntegerOut]", directorinattributes="[DirectorIntegerIn]") int "int"
|
||||
%feature("director") YetMoreStations;
|
||||
|
||||
%inline %{
|
||||
struct YetMoreStations {
|
||||
virtual int Slough(int x) {}
|
||||
virtual ~YetMoreStations() {}
|
||||
};
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@
|
|||
"$csclassname.getCPtr(d$csinput)"
|
||||
|
||||
// post only in csin typemap
|
||||
%typemap(csin, post=" int size = $csinput.Count;\n for (int i=0; i<size; ++i) {\n $csinput[i] /= 100;\n }") std::vector<double> &vpost
|
||||
%typemap(csin, post=" int size = $csinput.Count;\n"
|
||||
" for (int i=0; i<size; ++i) {\n"
|
||||
" $csinput[i] /= 100;\n"
|
||||
" }") std::vector<double> &vpost
|
||||
"$csclassname.getCPtr($csinput)"
|
||||
|
||||
%inline %{
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@
|
|||
|
||||
|
||||
// tests valuewrapper
|
||||
%feature("compactdefaultargs") MyClass2::set;
|
||||
%inline %{
|
||||
enum MyType { Val1, Val2 };
|
||||
|
||||
|
|
@ -134,6 +135,7 @@
|
|||
void set(MyClass1 cl1 = Val1) {}
|
||||
// This could have been written : set(MyClass1 cl1 = MyClass1(Val1))
|
||||
// But it works in C++ since there is a "conversion" constructor in MyClass1.
|
||||
void set2(MyClass1 cl1 = Val1) {}
|
||||
};
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ This was reported in bug #909389 */
|
|||
|
||||
%module derived_nested
|
||||
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::CC;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::DD;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::EE;
|
||||
%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::FF;
|
||||
|
||||
%inline %{
|
||||
|
||||
class A { int x; };
|
||||
|
|
@ -11,5 +16,12 @@ class B {
|
|||
class D : public A { int z; }; //ok
|
||||
};
|
||||
|
||||
struct BB {
|
||||
class CC { int y; };
|
||||
class DD : public A { int z; };
|
||||
struct EE : public A { int z; };
|
||||
struct FF : public A { int z; } ff_instance; // Bug 1960977
|
||||
void useEE(const EE& e) {}
|
||||
};
|
||||
%}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@
|
|||
%feature("director") Foo;
|
||||
|
||||
%newobject Foo::cloner();
|
||||
%newobject Foo::get_class();
|
||||
%newobject Bar::cloner();
|
||||
%newobject Bar::get_class();
|
||||
|
||||
|
||||
%inline {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@
|
|||
|
||||
%newobject *::create();
|
||||
|
||||
#ifdef SWIGPHP
|
||||
// TODO: Currently we do not track the dynamic type of returned objects
|
||||
// in PHP, so we need the factory helper.
|
||||
%include factory.i
|
||||
%factory(Foo *Bar::create, Bar);
|
||||
#endif
|
||||
|
||||
%rename(a) Bar::hello;
|
||||
%rename(s) Foo::p;
|
||||
%rename(q) Foo::r;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@
|
|||
%feature("director") Foo;
|
||||
|
||||
%feature("director:except") {
|
||||
#ifndef SWIGPHP
|
||||
if ($error != NULL) {
|
||||
#else
|
||||
if ($error == FAILURE) {
|
||||
#endif
|
||||
throw Swig::DirectorMethodException();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
%module(directors="1",dirprot="1") director_using
|
||||
|
||||
%warnfilter(SWIGWARN_PHP_PUBLIC_BASE) FooBar;
|
||||
|
||||
%{
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
|
|
|||
|
|
@ -487,11 +487,53 @@ struct Instances {
|
|||
// Repeated values
|
||||
#if defined(SWIGJAVA)
|
||||
%javaconst(1);
|
||||
// needed for typesafe and proper enums only
|
||||
%javaconst(0) ignoreA_three;
|
||||
%javaconst(0) ignoreA_thirteen;
|
||||
#elif defined(SWIGCSHARP)
|
||||
// needed for typesafe enums only
|
||||
#ifdef SWIG_TEST_NOCSCONST
|
||||
%csconst(0) ignoreA_three;
|
||||
%csconst(0) ignoreA_thirteen;
|
||||
#endif
|
||||
%csconst(1);
|
||||
#endif
|
||||
|
||||
#if defined(SWIGPERL)
|
||||
%ignore ignoreA_one;
|
||||
%ignore ignoreA_two;
|
||||
%ignore ignoreA_twelve;
|
||||
%ignore ignoreA_thirty_one;
|
||||
|
||||
%ignore ignoreB_ten;
|
||||
%ignore ignoreB_twenty;
|
||||
%ignore ignoreB_thirty;
|
||||
%ignore ignoreB_forty;
|
||||
|
||||
%ignore ignoreC_eleven;
|
||||
%ignore ignoreC_thirty_one;
|
||||
%ignore ignoreC_forty_one;
|
||||
|
||||
%ignore ignoreD_ten;
|
||||
%ignore ignoreD_twenty;
|
||||
|
||||
%ignore ignoreE_twenty;
|
||||
|
||||
%inline %{
|
||||
struct IgnoreTest {
|
||||
enum IgnoreA { ignoreA_zero, ignoreA_one, ignoreA_two, ignoreA_three, ignoreA_ten=10, ignoreA_eleven, ignoreA_twelve, ignoreA_thirteen, ignoreA_fourteen, ignoreA_twenty=20, ignoreA_thirty=30, ignoreA_thirty_one, ignoreA_thirty_two, ignoreA_thirty_three };
|
||||
enum IgnoreB { ignoreB_ten=10, ignoreB_eleven, ignoreB_twelve, ignoreB_twenty=20, ignoreB_thirty=30, ignoreB_thirty_one, ignoreB_thirty_two, ignoreB_forty=40, ignoreB_forty_one, ignoreB_forty_two };
|
||||
enum IgnoreC { ignoreC_ten=10, ignoreC_eleven, ignoreC_twelve, ignoreC_twenty=20, ignoreC_thirty=30, ignoreC_thirty_one, ignoreC_thirty_two, ignoreC_forty=40, ignoreC_forty_one, ignoreC_forty_two };
|
||||
enum IgnoreD { ignoreD_ten=10, ignoreD_twenty=20, ignoreD_twenty_one, ignoreD_twenty_two };
|
||||
enum IgnoreE { ignoreE_zero, ignoreE_twenty=20, ignoreE_twenty_one, ignoreE_twenty_two };
|
||||
};
|
||||
|
||||
IgnoreTest::IgnoreA ignoreATest(IgnoreTest::IgnoreA n) { return n; }
|
||||
IgnoreTest::IgnoreB ignoreBTest(IgnoreTest::IgnoreB n) { return n; }
|
||||
IgnoreTest::IgnoreC ignoreCTest(IgnoreTest::IgnoreC n) { return n; }
|
||||
IgnoreTest::IgnoreD ignoreDTest(IgnoreTest::IgnoreD n) { return n; }
|
||||
IgnoreTest::IgnoreE ignoreETest(IgnoreTest::IgnoreE n) { return n; }
|
||||
%}
|
||||
|
||||
%inline %{
|
||||
|
||||
namespace RepeatSpace {
|
||||
|
|
@ -509,24 +551,3 @@ repeat repeatTest(repeat e) { return e; }
|
|||
|
||||
%}
|
||||
|
||||
#else
|
||||
%inline %{
|
||||
|
||||
namespace RepeatSpace {
|
||||
typedef enum
|
||||
{
|
||||
one = 1,
|
||||
initial = one,
|
||||
two,
|
||||
three,
|
||||
last = three,
|
||||
end = last
|
||||
} repeat;
|
||||
repeat repeatTest(repeat e) { return e; }
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -3,5 +3,7 @@
|
|||
// Test enum wrapping using the typesafe enum pattern in the target language
|
||||
%include "enumtypesafe.swg"
|
||||
|
||||
#define SWIG_TEST_NOCSCONST // For C# typesafe enums
|
||||
|
||||
%include "enum_thorough.i"
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) globalinstance1;
|
||||
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) globalinstance2;
|
||||
%warnfilter(SWIGWARN_RUBY_WRONG_NAME) globalinstance3;
|
||||
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK);
|
||||
|
||||
%inline %{
|
||||
|
||||
|
|
@ -32,8 +33,14 @@ bar3(foo3 x) {}
|
|||
|
||||
enum sad { boo, hoo = 5 };
|
||||
|
||||
#ifdef __cplusplus /* For Octave and g++ which compiles C test code as C++ */
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Unnamed enum instance */
|
||||
enum { globalinstance1, globalinstance2, globalinstance3 = 30 } GlobalInstance;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Anonymous enum */
|
||||
enum { AnonEnum1, AnonEnum2 = 100 };
|
||||
|
|
@ -58,7 +65,7 @@ typedef struct _iFoo
|
|||
enum {
|
||||
Phoo = +50,
|
||||
Char = 'a'
|
||||
} e;
|
||||
} e;
|
||||
} iFoo;
|
||||
%}
|
||||
#else
|
||||
|
|
@ -71,5 +78,20 @@ struct iFoo
|
|||
};
|
||||
};
|
||||
%}
|
||||
|
||||
#endif
|
||||
|
||||
// enum declaration and initialization
|
||||
%inline %{
|
||||
enum Exclamation {
|
||||
goodness,
|
||||
gracious,
|
||||
me
|
||||
} enumInstance = me;
|
||||
|
||||
enum ContainYourself {
|
||||
slap = 10,
|
||||
my,
|
||||
thigh
|
||||
} Slap = slap, My = my, Thigh = thigh, *pThigh = &Thigh, arrayContainYourself[3] = {slap, my, thigh};
|
||||
%}
|
||||
|
||||
|
|
|
|||
16
Examples/test-suite/extern_c.i
Normal file
16
Examples/test-suite/extern_c.i
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
%module extern_c
|
||||
|
||||
%inline %{
|
||||
extern "C" {
|
||||
void RealFunction(int value);
|
||||
typedef void Function1(int value); // Fails
|
||||
typedef int Integer1;
|
||||
}
|
||||
typedef void Function2(int value); // Works
|
||||
typedef int Integer2;
|
||||
%}
|
||||
|
||||
%{
|
||||
void RealFunction(int value) {}
|
||||
%}
|
||||
|
||||
|
|
@ -11,8 +11,8 @@ class Klass6 {};
|
|||
class Klass7 {};
|
||||
|
||||
struct KlassMethods {
|
||||
static void methodA(::Klass1 v, const ::Klass2 cv, const ::Klass3 *cp, ::Klass4 *p, const ::Klass5 &cr, ::Klass6 &r, Klass7*& pr) {}
|
||||
static void methodB( Klass1 v, const Klass2 cv, const Klass3 *cp, Klass4 *p, const Klass5 &cr, Klass6 &r, Klass7*& pr) {}
|
||||
static void methodA(::Klass1 v, const ::Klass2 cv, const ::Klass3 *cp, ::Klass4 *p, const ::Klass5 &cr, ::Klass6 &r, ::Klass7*& pr) {}
|
||||
static void methodB( Klass1 v, const Klass2 cv, const Klass3 *cp, Klass4 *p, const Klass5 &cr, Klass6 &r, Klass7*& pr) {}
|
||||
};
|
||||
%}
|
||||
|
||||
|
|
@ -28,8 +28,8 @@ class XYZ7 {};
|
|||
}
|
||||
|
||||
struct XYZMethods {
|
||||
static void methodA(::Space::XYZ1 v, const ::Space::XYZ2 cv, const ::Space::XYZ3 *cp, ::Space::XYZ4 *p, const ::Space::XYZ5 &cr, ::Space::XYZ6 &r, Space::XYZ7*& pr) {}
|
||||
static void methodB( Space::XYZ1 v, const Space::XYZ2 cv, const Space::XYZ3 *cp, Space::XYZ4 *p, const Space::XYZ5 &cr, Space::XYZ6 &r, Space::XYZ7*& pr) {}
|
||||
static void methodA(::Space::XYZ1 v, const ::Space::XYZ2 cv, const ::Space::XYZ3 *cp, ::Space::XYZ4 *p, const ::Space::XYZ5 &cr, ::Space::XYZ6 &r, ::Space::XYZ7*& pr) {}
|
||||
static void methodB( Space::XYZ1 v, const Space::XYZ2 cv, const Space::XYZ3 *cp, Space::XYZ4 *p, const Space::XYZ5 &cr, Space::XYZ6 &r, Space::XYZ7*& pr) {}
|
||||
};
|
||||
%}
|
||||
|
||||
|
|
|
|||
44
Examples/test-suite/global_scope_types.i
Normal file
44
Examples/test-suite/global_scope_types.i
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
%module global_scope_types
|
||||
|
||||
// no constructor/destructor wrappers as they do not use global scope operator which we are trying to test here
|
||||
%nodefaultctor Dingaling;
|
||||
%nodefaultdtor Dingaling;
|
||||
|
||||
%inline %{
|
||||
struct Dingaling {};
|
||||
typedef Dingaling DINGALING;
|
||||
template <typename T> struct MyTemplate {
|
||||
T tt(T t) { return t; }
|
||||
T& ttr(T& t) { return t; }
|
||||
};
|
||||
|
||||
#ifndef SWIG
|
||||
// This is added so that the code will not compile, if the global scope operator on Dingaling is omitted in the generated code
|
||||
namespace Spac {
|
||||
class Dingaling {
|
||||
Dingaling();
|
||||
Dingaling(const Dingaling& t);
|
||||
Dingaling& operator=(const Dingaling t);
|
||||
};
|
||||
}
|
||||
using namespace Spac;
|
||||
#endif
|
||||
|
||||
namespace Spac {
|
||||
|
||||
struct Ting {};
|
||||
typedef Ting TING;
|
||||
|
||||
class Test {
|
||||
public:
|
||||
void something(::Dingaling t, ::Dingaling* pt, ::Dingaling& rt, const ::Dingaling& crt) {}
|
||||
void tsomething(MyTemplate< ::Dingaling > t1, MyTemplate< const ::Dingaling* > t2) {}
|
||||
// void usomething(::MyTemplate< ::DINGALING > t3, ::MyTemplate< ::DINGALING *> t4) {} // needs fixing
|
||||
void nothing(::Spac::Ting*, ::Spac::TING&) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void funcptrtest( void (*)(::Dingaling) ) {}
|
||||
%}
|
||||
|
||||
|
|
@ -9,14 +9,22 @@ srcdir = @srcdir@
|
|||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @top_builddir@
|
||||
GUILE = @GUILE@
|
||||
GUILE_RUNTIME=-runtime
|
||||
|
||||
C_TEST_CASES = long_long \
|
||||
list_vector \
|
||||
multivalue \
|
||||
pointer_in_out
|
||||
|
||||
C_TEST_CASES = long_long list_vector pointer_in_out multivalue
|
||||
|
||||
include $(srcdir)/../common.mk
|
||||
|
||||
# Overridden variables here
|
||||
# none!
|
||||
|
||||
# Custom tests - tests with additional commandline options
|
||||
%.multicpptest: SWIGOPT += $(GUILE_RUNTIME)
|
||||
|
||||
# Rules for the different types of tests
|
||||
%.cpptest:
|
||||
$(setup)
|
||||
|
|
@ -28,19 +36,6 @@ include $(srcdir)/../common.mk
|
|||
+$(swig_and_compile_c)
|
||||
$(run_testcase)
|
||||
|
||||
# override the default in common.mk by adding SWIGOPT +=
|
||||
swig_and_compile_multi_cpp = \
|
||||
for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
|
||||
SWIGOPT=" -runtime "; \
|
||||
export SWIGOPT; \
|
||||
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile CXXSRCS="$(CXXSRCS)" \
|
||||
SWIG_LIB="$(SWIG_LIB)" SWIG="$(SWIG)" LIBS='$(LIBS)' \
|
||||
INCLUDES="$(INCLUDES)" SWIGOPT="$(SWIGOPT) $$SWIGOPT" NOLINK=true \
|
||||
TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR="$(INTERFACEDIR)" INTERFACE="$$f.i" \
|
||||
$(LANGUAGE)$(VARIANT)_cpp; \
|
||||
SWIGOPT=" -noruntime "; \
|
||||
done
|
||||
|
||||
%.multicpptest:
|
||||
$(setup)
|
||||
+$(swig_and_compile_multi_cpp)
|
||||
|
|
@ -49,9 +44,9 @@ swig_and_compile_multi_cpp = \
|
|||
# Runs the testcase. A testcase is only run if
|
||||
# a file is found which has _runme.scm appended after the testcase name.
|
||||
run_testcase = \
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then ( \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(GUILE) -l $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX);) \
|
||||
fi;
|
||||
if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
|
||||
env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(GUILE) -l $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
|
||||
fi
|
||||
|
||||
# Clean
|
||||
%.clean:
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue