Merge branch 'master' into javalist

This commit is contained in:
Alan Woodland 2017-06-05 21:55:12 +01:00
commit 4db1300622
798 changed files with 26703 additions and 7774 deletions

View file

@ -4,9 +4,16 @@ matrix:
- compiler: clang - compiler: clang
os: linux os: linux
env: SWIGLANG= env: SWIGLANG=
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG= env: SWIGLANG=
- compiler: gcc
os: linux
env: SWIGLANG=
sudo: required
dist: trusty
- os: linux - os: linux
env: SWIGLANG= SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 env: SWIGLANG= SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
sudo: required sudo: required
@ -18,12 +25,18 @@ matrix:
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=csharp env: SWIGLANG=csharp
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=d env: SWIGLANG=d
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=go env: SWIGLANG=go
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=go VER=1.5 env: SWIGLANG=go VER=1.5
@ -32,21 +45,31 @@ matrix:
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=guile env: SWIGLANG=guile
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=java env: SWIGLANG=java
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=javascript ENGINE=node env: SWIGLANG=javascript ENGINE=node
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=javascript ENGINE=jsc env: SWIGLANG=javascript ENGINE=jsc
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=javascript ENGINE=v8 env: SWIGLANG=javascript ENGINE=v8
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=lua env: SWIGLANG=lua
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=lua VER=5.3 env: SWIGLANG=lua VER=5.3
@ -54,77 +77,157 @@ matrix:
dist: trusty dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=octave SWIGJOBS=-j2 # 3.2 env: SWIGLANG=ocaml
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=octave SWIGJOBS=-j2 VER=3.8 env: SWIGLANG=octave SWIGJOBS=-j2 # 3.8
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=octave SWIGJOBS=-j2 VER=4.0 env: SWIGLANG=octave SWIGJOBS=-j2 VER=4.0
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=octave SWIGJOBS=-j2 VER=4.2 CPP11=1
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=perl5 env: SWIGLANG=perl5
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=php env: SWIGLANG=php5
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=php VER=7.0
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=php VER=7.1
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python VER=2.4 env: SWIGLANG=python VER=2.4
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python VER=2.5 env: SWIGLANG=python VER=2.5
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python VER=2.6 env: SWIGLANG=python VER=2.6
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python # 2.7 env: SWIGLANG=python # 2.7
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python PY3=3 # 3.2 env: SWIGLANG=python PY3=3 VER=3.2
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python PY3=3 VER=3.3 env: SWIGLANG=python PY3=3 VER=3.3
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python PY3=3 VER=3.4 env: SWIGLANG=python PY3=3 VER=3.4
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python PY3=3 VER=3.5 env: SWIGLANG=python PY3=3 VER=3.5
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin VER=2.6
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin env: SWIGLANG=python SWIG_FEATURES=-builtin
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5 env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5 SWIGOPTPY3=
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python SWIG_FEATURES=-O env: SWIGLANG=python SWIG_FEATURES=-O
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python SWIG_FEATURES=-classic env: SWIGLANG=python SWIG_FEATURES=-classic
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=r env: SWIGLANG=r
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=ruby env: SWIGLANG=ruby VER=1.9.3
sudo: required
dist: trusty
- compiler: gcc
os: linux
env: SWIGLANG=ruby VER=2.0.0
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=ruby VER=2.3.0 env: SWIGLANG=ruby VER=2.3.0
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=scilab env: SWIGLANG=scilab
sudo: required
dist: trusty
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=tcl env: SWIGLANG=tcl
sudo: required
dist: trusty
- os: linux - os: linux
env: SWIGLANG=csharp SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 env: SWIGLANG=csharp SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
sudo: required sudo: required
dist: trusty dist: trusty
- os: linux
env: SWIGLANG=go SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
sudo: required
dist: trusty
- os: linux - os: linux
env: SWIGLANG=java SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 env: SWIGLANG=java SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
sudo: required sudo: required
@ -133,10 +236,22 @@ matrix:
env: SWIGLANG=python SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1 env: SWIGLANG=python SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
sudo: required sudo: required
dist: trusty dist: trusty
- os: linux
env: SWIGLANG=ruby SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
sudo: required
dist: trusty
- os: linux
env: SWIGLANG=tcl SWIG_CC=gcc-5 SWIG_CXX=g++-5 CPP11=1
sudo: required
dist: trusty
- os: linux - os: linux
env: SWIGLANG=csharp SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1 env: SWIGLANG=csharp SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
sudo: required sudo: required
dist: trusty dist: trusty
- os: linux
env: SWIGLANG=go SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
sudo: required
dist: trusty
- os: linux - os: linux
env: SWIGLANG=java SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1 env: SWIGLANG=java SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
sudo: required sudo: required
@ -145,8 +260,17 @@ matrix:
env: SWIGLANG=python SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1 env: SWIGLANG=python SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
sudo: required sudo: required
dist: trusty dist: trusty
- os: osx - os: linux
env: SWIGLANG= SWIG_CC=gcc-4.2 SWIG_CXX=g++-4.2 env: SWIGLANG=ruby SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
sudo: required
dist: trusty
- os: linux
env: SWIGLANG=tcl SWIG_CC=gcc-6 SWIG_CXX=g++-6 CPP14=1
sudo: required
dist: trusty
- compiler: gcc
os: osx
env: SWIGLANG=
- compiler: clang - compiler: clang
os: osx os: osx
env: SWIGLANG= env: SWIGLANG=
@ -170,7 +294,7 @@ matrix:
env: SWIGLANG=perl5 env: SWIGLANG=perl5
- compiler: clang - compiler: clang
os: osx os: osx
env: SWIGLANG=php env: SWIGLANG=php5
- compiler: clang - compiler: clang
os: osx os: osx
env: SWIGLANG=python env: SWIGLANG=python
@ -185,14 +309,22 @@ matrix:
env: SWIGLANG=tcl env: SWIGLANG=tcl
allow_failures: allow_failures:
# Started failing after upgrade from Guile 2.0.14 to Guile 2.2.0
- compiler: clang
os: osx
env: SWIGLANG=guile
# Lots of failing tests currently # Lots of failing tests currently
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=ocaml env: SWIGLANG=ocaml
sudo: required
dist: trusty
# Not quite working yet # Not quite working yet
- compiler: gcc - compiler: gcc
os: linux os: linux
env: SWIGLANG=python SWIG_FEATURES=-O env: SWIGLANG=python SWIG_FEATURES=-O
sudo: required
dist: trusty
before_install: before_install:
- date -u - date -u
- uname -a - uname -a
@ -233,6 +365,3 @@ script:
- echo 'Cleaning...' && echo -en 'travis_fold:start:script.3\\r' - echo 'Cleaning...' && echo -en 'travis_fold:start:script.3\\r'
- make check-maintainer-clean && ../../configure $CONFIGOPTS - make check-maintainer-clean && ../../configure $CONFIGOPTS
- echo -en 'travis_fold:end:script.3\\r' - echo -en 'travis_fold:end:script.3\\r'
branches:
only:
- master

View file

@ -1,8 +1,8 @@
*** ANNOUNCE: SWIG 3.0.10 (in progress) *** *** ANNOUNCE: SWIG 4.0.0 (in progress) ***
http://www.swig.org http://www.swig.org
We're pleased to announce SWIG-3.0.10, the latest SWIG release. We're pleased to announce SWIG-4.0.0, the latest SWIG release.
What is SWIG? What is SWIG?
============= =============
@ -27,11 +27,11 @@ Availability
============ ============
The release is available for download on Sourceforge at The release is available for download on Sourceforge at
http://prdownloads.sourceforge.net/swig/swig-3.0.10.tar.gz http://prdownloads.sourceforge.net/swig/swig-4.0.0.tar.gz
A Windows version is also available at A Windows version is also available at
http://prdownloads.sourceforge.net/swig/swigwin-3.0.10.zip http://prdownloads.sourceforge.net/swig/swigwin-4.0.0.zip
Please report problems with this release to the swig-devel mailing list, Please report problems with this release to the swig-devel mailing list,
details at http://www.swig.org/mail.html. details at http://www.swig.org/mail.html.

View file

@ -130,6 +130,7 @@ static void failed(void)
exit(1); exit(1);
} }
args_add_prefix(orig_args, p); args_add_prefix(orig_args, p);
free(p);
} }
if (ccache_verbose) { if (ccache_verbose) {
@ -490,7 +491,9 @@ static void find_hash(ARGS *args)
/* also include the hash of the compiler name - as some compilers /* also include the hash of the compiler name - as some compilers
use hard links and behave differently depending on the real name */ use hard links and behave differently depending on the real name */
if (st.st_nlink > 1) { if (st.st_nlink > 1) {
hash_string(str_basename(args->argv[0])); char *path = str_basename(args->argv[0]);
hash_string(path);
free(path);
} }
hash_int(st.st_size); hash_int(st.st_size);
@ -523,6 +526,7 @@ static void find_hash(ARGS *args)
input_base, tmp_string(), input_base, tmp_string(),
i_extension); i_extension);
x_asprintf(&path_stderr, "%s/tmp.cpp_stderr.%s", temp_dir, tmp_string()); x_asprintf(&path_stderr, "%s/tmp.cpp_stderr.%s", temp_dir, tmp_string());
free(input_base);
if (!direct_i_file) { if (!direct_i_file) {
/* run cpp on the input file to obtain the .i */ /* run cpp on the input file to obtain the .i */
@ -781,6 +785,7 @@ static void find_compiler(int argc, char **argv)
/* support user override of the compiler */ /* support user override of the compiler */
if ((path=getenv("CCACHE_CC"))) { if ((path=getenv("CCACHE_CC"))) {
free(base);
base = x_strdup(path); base = x_strdup(path);
} }
@ -791,8 +796,10 @@ static void find_compiler(int argc, char **argv)
stats_update(STATS_COMPILER); stats_update(STATS_COMPILER);
cc_log("could not find compiler (%s)\n", base); cc_log("could not find compiler (%s)\n", base);
perror(base); perror(base);
free(base);
exit(1); exit(1);
} }
free(base);
} }
@ -1076,6 +1083,7 @@ static void process_args(int argc, char **argv)
if (strlen(p) < 2) { if (strlen(p) < 2) {
cc_log("badly formed dependency file %s\n", output_file); cc_log("badly formed dependency file %s\n", output_file);
stats_update(STATS_ARGS); stats_update(STATS_ARGS);
free(default_depfile_name);
failed(); failed();
return; return;
} }
@ -1093,6 +1101,7 @@ static void process_args(int argc, char **argv)
strcat(default_depfile_name, ".d"); strcat(default_depfile_name, ".d");
args_add(stripped_args, "-MF"); args_add(stripped_args, "-MF");
args_add(stripped_args, default_depfile_name); args_add(stripped_args, default_depfile_name);
free(default_depfile_name);
} }
if (!dependency_target_specified) { if (!dependency_target_specified) {
@ -1117,6 +1126,7 @@ static void process_args(int argc, char **argv)
exit(1); exit(1);
} }
args_add_prefix(stripped_args, p); args_add_prefix(stripped_args, p);
free(p);
} }
} }
@ -1305,6 +1315,7 @@ static void setup_uncached_err(void)
if (putenv(buf) == -1) { if (putenv(buf) == -1) {
cc_log("putenv failed\n"); cc_log("putenv failed\n");
close(uncached_fd);
stats_update(STATS_ERROR); stats_update(STATS_ERROR);
failed(); failed();
} }

View file

@ -267,6 +267,7 @@ char *find_executable(const char *name, const char *exclude_name)
} }
free(fname); free(fname);
} }
free(path);
return NULL; return NULL;
#endif #endif

View file

@ -138,7 +138,10 @@ static void stats_update_size(enum stats stat, size_t size, size_t numfiles)
memset(counters, 0, sizeof(counters)); memset(counters, 0, sizeof(counters));
if (lock_fd(fd) != 0) return; if (lock_fd(fd) != 0) {
close(fd);
return;
}
/* read in the old stats */ /* read in the old stats */
stats_read_fd(fd, counters); stats_read_fd(fd, counters);

View file

@ -281,6 +281,7 @@ int unify_hash(const char *fname)
fd = open(fname, O_RDONLY|O_BINARY); fd = open(fname, O_RDONLY|O_BINARY);
if (fd == -1 || fstat(fd, &st) != 0) { if (fd == -1 || fstat(fd, &st) != 0) {
cc_log("Failed to open preprocessor output %s\n", fname); cc_log("Failed to open preprocessor output %s\n", fname);
if (fd != -1) close(fd);
stats_update(STATS_PREPROCESSOR); stats_update(STATS_PREPROCESSOR);
return -1; return -1;
} }
@ -289,12 +290,12 @@ int unify_hash(const char *fname)
lines in preprocessor output. I have seen lines of over lines in preprocessor output. I have seen lines of over
100k in length, so this is well worth it */ 100k in length, so this is well worth it */
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
if (map == (char *)-1) { if (map == (char *)-1) {
cc_log("Failed to mmap %s\n", fname); cc_log("Failed to mmap %s\n", fname);
stats_update(STATS_PREPROCESSOR); stats_update(STATS_PREPROCESSOR);
return -1; return -1;
} }
close(fd);
/* pass it through the unifier */ /* pass it through the unifier */
unify((unsigned char *)map, st.st_size); unify((unsigned char *)map, st.st_size);

View file

@ -189,9 +189,11 @@ void copy_fd(int fd_in, int fd_out) {
while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) { while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) {
if (write(fd_out, buf, n) != n) { if (write(fd_out, buf, n) != n) {
gzclose(gz_in);
fatal("Failed to copy fd"); fatal("Failed to copy fd");
} }
} }
gzclose(gz_in);
} }
static int _copy_file(const char *src, const char *dest, int mode) { static int _copy_file(const char *src, const char *dest, int mode) {
@ -248,9 +250,11 @@ static int _copy_file(const char *src, const char *dest, int mode) {
} }
if (mode == COPY_TO_CACHE) { if (mode == COPY_TO_CACHE) {
gz_out = gzdopen(dup(fd_out), "wb"); int dup_fd_out = dup(fd_out);
gz_out = gzdopen(dup_fd_out, "wb");
if (!gz_out) { if (!gz_out) {
gzclose(gz_in); gzclose(gz_in);
close(dup_fd_out);
close(fd_out); close(fd_out);
free(tmp_name); free(tmp_name);
return -1; return -1;
@ -459,6 +463,7 @@ int create_cachedirtag(const char *dir)
f = fopen(filename, "w"); f = fopen(filename, "w");
if (!f) goto error; if (!f) goto error;
if (fwrite(CACHEDIR_TAG, sizeof(CACHEDIR_TAG)-1, 1, f) != 1) { if (fwrite(CACHEDIR_TAG, sizeof(CACHEDIR_TAG)-1, 1, f) != 1) {
fclose(f);
goto error; goto error;
} }
if (fclose(f)) goto error; if (fclose(f)) goto error;
@ -485,7 +490,7 @@ void x_asprintf(char **ptr, const char *format, ...)
} }
va_end(ap); va_end(ap);
if (!ptr) fatal("out of memory in x_asprintf"); if (!*ptr) fatal("out of memory in x_asprintf");
} }
/* /*

492
CHANGES
View file

@ -2,6 +2,492 @@ SWIG (Simplified Wrapper and Interface Generator)
See the CHANGES.current file for changes in the current version. See the CHANGES.current file for changes in the current version.
See the RELEASENOTES file for a summary of changes in each release. See the RELEASENOTES file for a summary of changes in each release.
Issue # numbers mentioned below can be found on Github. For more details, add
the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 3.0.12 (27 Jan 2017)
============================
2017-01-27: wsfulton
[C#] #882 Fix missing filename in error messages when there is a problem
writing out C# files.
2017-01-27: briancaine
[Guile] #744 Fix compilation errors in Guile wrappers - regression
introduced in swig-3.0.11.
2017-01-24: andrey-starodubtsev
[Java] Apply #704 - director typemap improvements.
Memory leak fixes, add support for "directorargout" typemap and
add director support to typemaps.i.
2017-01-24: wsfulton
Enhance %extend to extend a class with template constructors, eg:
struct Foo {
%extend {
template<typename T>
Foo(int a, T b) {
...
}
}
};
%template(Foo) Foo::Foo<double>;
2017-01-22: wsfulton
Issue #876 Enhance %extend to extend a class with template methods, eg:
struct Foo {
%extend {
template<typename T>
void do_stuff(int a, T b) {
...
}
}
};
%template(do_stuff_inst) Foo::do_stuff<double>;
Similarly for static template methods.
2017-01-22: kwwette
[Octave] add support for version 4.2
- The Octave API now uses some C++11 features. It is recommended to use
the mkoctfile program supplied by Octave to compile the SWIG-generated
wrapper code, as mkoctfile will ensure the correct C++ compiler/options
are used. Otherwise, the value of `mkoctfile -p CXX` should be parsed
for any -std=* flags which might be present.
- Octave has dropped support for << and >> operators, so SWIG now
ignores them.
- The Octave error() function now raises C++ exceptions to propagate
Octave errors, so %exception directives may need to be modified.
For convenience the SWIG_RETHROW_OCTAVE_EXCEPTIONS macro can be used
to rethrow any Octave exceptions for Octave itself to handle, e.g.:
try {
$action // may call error()
}
SWIG_RETHROW_OCTAVE_EXCEPTIONS // error() exceptions are rethrown
catch(...) {
... // all other exceptions
}
*** POTENTIAL INCOMPATIBILITY ***
2017-01-16: wkalinin
[C#] Fix #733 regression introduced in swig-3.0.9.
Missing virtual function override in C# layer when using %import.
2017-01-16: fschlimb
Fix #813 template symbol name lookup bug when typedef names are the same but in different
namespaces.
2017-01-15: wsfulton
[C# D Java]
The SWIG library no longer uses the javatype, dtype or cstype typemaps, thereby
completely freeing them up for users to use without having to replicate the library
code that they previously added. The code previously generated by these typemaps
has been replaced by the new %proxycode directive. Their use in the library code
was fairly minimal:
C# cstype: std_array.i std_map.i std_vector.i
D dtype: std_vector.i
Java javatype: arrays_java.i
2017-01-14: wsfulton
The %extend directive can now optionally support one of the 'class', 'struct' or 'union'
keywords before the identifier name, for example:
struct X { ... };
%extend struct X { ... }
Previously this had to specified as:
struct X { ... };
%extend X { ... }
2017-01-13: wsfulton
[C# D Java] Add new %proxycode directive which is a macro for %insert("proxycode").
This is a way of adding pure C#/D/Java code into the appropriate proxy class, eg:
%extend Proxy2 {
%proxycode %{
public int proxycode2(int i) {
return i+2;
}
%}
}
%inline %{
struct Proxy2 {};
%}
There will then be a pure Java/C#/D method called proxycode2 in the Proxy2 class.
2016-12-31: ajrheading1
Issue #860 - Remove use of std::unary_function and std::binary_function
which is deprecated in C++11.
2016-12-30: olly
[PHP7] Register internal 'swig_runtime_data_type_pointer' constant
as "CONST_PERSISTENT" to avoid segmentation fault on module unload.
Fixes #859 reported by Timotheus Pokorra. Thanks also to Javier Torres
for a minimal reproducer.
Version 3.0.11 (29 Dec 2016)
============================
2016-12-24: wsfulton
[C#] Add %feature("csdirectordelegatemodifiers") to enable customization
of the delegate access modifiers generated in director classes.
Fixes issue #748.
2016-12-23: wsfulton
[Python] Fix builtin "python:slot" feature failing for tp_hash when using
hashfunc closure with a "Wrong type for hash function" for Python 2.
Issue #843.
2016-12-21: joequamt
Changed generation of functions so that only functions
that end in _set generate accessor functions rather than
looking for "set".
Change generation of operators to not have underscores
to start in R. Users need to provide custom names for these operator overloads.
2016-12-21: olly
Fix isfinite() checks to work with all C++11 compilers.
Fixes issues #615, #788 and #849.
2016-12-20: wsfulton
%namewarn unnecessarily caused keyword warnings for non-instantiated template classes
and duplicate warnings for instantiated template classes when keywords were used.
Issue #845.
2016-12-18: ezralanglois
[Python, Ruby, Octave] Memory leak fix on error in std::pair wrappers.
Issue #851.
2016-12-18: wsfulton
Zero initialize arrays when using %array_class and %array_functions.
2016-12-18: t-ikegami
[Python] Fix #446
Python %array_class of carrays.i failed with -builtin option.
2016-12-16: briancaine
[Guile] Patch #744 Added support for Guile's native pointer functionality
2016-12-01: wsfulton
[Python] Issue #769.
Add optional moduleimport attribute to %module so that the
default module import code can be overridden. See the "Searching for the wrapper module"
documentation in Python.html. Example:
%module(moduleimport="import _foo") foo
$module also expands to the low-level C/C++ module name, so the following is the
same as above
%module(moduleimport="import $module") foo
2016-11-30: olly
[PHP] Add support for PHP7. PHP5's C extension API has changed
substantially so you need to use -php7 to specify you want PHP7
compatible wrappers. The default extension for generated wrappers
is now .cxx (to match SWIG's default for every other language - to
generate foo_wrap.cpp you can run SWIG with -cppext cpp). Fixes
issue #571.
As part of this change, the language subdirectory for PHP5 has
changed from "php" to "php5" - if you are making use of the search
path feature where the language subdirectory of each directory
is also searched, you'll need to update your bindings. A simple
fix which works for older and newer SWIG is to add a symlink:
ln -s php php5
*** POTENTIAL INCOMPATIBILITY ***
2016-11-30: olly
[PHP] Only emit one copy of each distinct arginfo. Previously we
emitted a separate one for every wrapped function, but typically
many functions have the same number of parameters and combinations
of parameters passed by reference or not.
This change significantly reduces both the size of the generated
wrapper, and of the compiled PHP extension module (e.g. by ~6% for
the stripped extension module for Xapian's PHP7 bindings).
2016-11-28: wsfulton
Fix %rename override of wildcard %rename for templates. For example:
%rename(GlobalIntOperator) *::operator bool; // wildcard %rename
%rename(XIntOperator) X::operator bool; // fix now overrides first %rename above
OR
%rename(XIntOperator) X<int>::operator bool; // fix now overrides first %rename above
template<typename T> struct X {
operator bool();
...
};
%template(Xint) X<int>;
This also fixes %rename override of global %rename for templates. For example:
// Global rename to make all functions start with a lower case letter
%rename("%(firstlowercase)s", %$isfunction ) "";
%rename(woohoo) W::Woo; // fix now overrides above %rename
template<typename T> struct W {
W Woo();
...
};
%template(Wint) W<int>;
The above also introduces a possibly unexpected change. Many of the STL containers
provided by SWIG use %rename to rename some methods, eg in std::vector, push_back
is renamed to add in Java. Previously this intended rename did not happen when using
using global %rename rules and the method would remain as push_back, but is now
renamed to add. Some more info in issue #856.
*** POTENTIAL INCOMPATIBILITY ***
2016-11-26: m7thon
[Python] Issue #709 - improved wrapping of division operators
'from __future__ import division' now works in Python 2 whether or not the
-py3 flag is used.
2016-11-12: joequant
[R] Issue #697 - fix comma issue with overload methods
2016-11-12: joequant
[R] Issue #555 - R runtime needs stdio.h
2016-11-02: wsfulton
[Python] Issue #816 - fix compilation error when using -extranative and -builtin.
2016-11-02: liorgold
Patch #741 - Add support for C++11 alias templates, see updated CPlusPlus11.html
documentation.
2016-10-30: myd7349
[C#] Patch #740 Add std_array.i for C# for wrapping std::array.
Patch also enhances std::vector<std::wstring> C# wrappers with additional functions
(Contains, IndexOf, LastIndexOf and Remove).
2016-10-30: tobilau
[Java] Fix wrappers for wstring parameters in director methods to cleanup local
ref after director callback has finished.
2016-10-23: wsfulton
[C#] Add missing csdirectorin VOID_INT_PTR and csdirectorout VOID_INT_PTR typemaps.
2016-10-23: jiulongw
Patch #781 - Fix wrapping of C compound expressions containing char constants
in quotes such as:
#define H_SUPPRESS_SCALING_MAGIC (('s'<<24) | ('u'<<16) | ('p'<<8) | 'p')
enum DifferentTypes {
typecharcompound='A'+1,
typecharcompound2='B' << 2
};
2016-10-13: wsfulton
[Python] Issue #808 - fix Python pickling and metaclass for builtin wrappers.
The metaclass (SwigPyObjectType) for SWIG objects was not defined in
a way that let importlib successfully import the Python wrappers.
The pickle module previously failed to pickle objects because it couldn't
determine what module the SWIG wrapped objects were in.
2016-09-29: wsfulton
[Allegrocl, CFFI, GO, Javascript, Ocaml, R, Scilab]
Add missing support for the "ret" typemap in a few target languages.
The documentation also now has info on the "ret" typemap.
2016-09-27: ahmed-usman
[xml] Handle template parameters correctly.
2016-09-27: dontpanic92
[Go] Fix argument names in inherited functions taking more than 8
parameters. Fixes #795.
2016-09-26: smarchetto
[Scilab] mlists that map pointers can be given a custom type name.
2016-09-25: wsfulton
Patch #793 from q-p to expand exception handling to include std::bad_cast
in std_except.i.
2016-09-24: olly
[PHP] Fix code generated for feature("director:except") -
previously the return value of call_user_function() was ignored and
we checked an uninitialised value instead. Fixes #627. Based on
patch from Sergey Seroshtan.
2016-09-22: wsfulton
[Python] More flexible python builtin slots for overloaded C++ function.
The closure names used for builtin slots are mangled with their functype so
that overloaded C++ method names can be used for multiple slots.
For example:
%feature("python:slot", "mp_subscript", functype="binaryfunc") SimpleArray::__getitem__;
%feature("python:slot", "sq_item", functype="ssizeargfunc") SimpleArray::__getitem__(Py_ssize_t n);
will generate closures:
SWIGPY_SSIZEARGFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___ssizeargfunc_closure */
SWIGPY_BINARYFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___binaryfunc_closure */
Previously only one name was defined: _wrap_SimpleArray___getitem___closure.
Hence the overloaded __getitem__ method can be used to support both mp_subscript and sq_item slots.
2016-09-17: wsfulton
[Python] Fix iterators for containers of NULL pointers (or Python None) when using
-builtin. Previously iteration would stop at the first element that was NULL.
2016-09-16: olly
[Javascript] Fix SWIG_exception() macro to return from the current
function. Fixes #789, reported by Julien Dutriaux.
2016-09-16: olly
[PHP] Fix SWIG_exception() macro to return from the current function.
Fixes #240, reported by Sergey Seroshtan.
2016-09-12: xypron
[C#] Patch #786 Keyword rename to be CLS compliant by adding an underscore
suffix instead of an underscore prefix to the C symbol name. Please use an explicit
%rename to rename the symbol with a _ prefix if you want the old symbol name.
*** POTENTIAL INCOMPATIBILITY ***
2016-09-09: olly
[Python] Fix import handling for Python 2.6 to work in a frozen
application. Fixes #145, reported by Thomas Kluyver.
2016-09-02: smarchetto
[Scilab] Pointers are mapped to mlist instead of tlist
(mlist better for scilab overloading)
2016-09-02: olly
[PHP] Fix "out" typemap for member function pointers and "in"
typemap for char INPUT[ANY].
2016-09-01: wsfulton
[Python] More efficient Python slicing.
Call reserve for container types that support it to avoid repeated
memory reallocations for new slices or slices that grow in size.
2016-09-01: wsfulton
[Python] #771 - Make builtin types hashable by default.
Default hash is the underlying C/C++ pointer. This matches up with testing for
equivalence (Py_EQ in SwigPyObject_richcompare) which compares the pointers.
2016-08-22: wsfulton
[Python] The following builtin slots can be customized like other slots via the
"python:<x>" and "python:slot" features where <x> is the appropriate slot name:
tp_allocs
tp_bases
tp_basicsize
tp_cache
tp_del
tp_dealloc
tp_flags
tp_frees
tp_getset
tp_is_gc
tp_maxalloc
tp_methods
tp_mro
tp_new
tp_next
tp_prev
tp_richcompare
tp_subclasses
tp_weaklist
was_sq_ass_slice
was_sq_slice
A few documentation improvements for slot customization.
2016-08-09: joequant
[R] Patch #765 Fix extern "C" header includes for C++ code.
2016-08-05: olly
[xml] Fix how the output filename is built to avoid problems when
it contains the embedded strings ".c", ".cpp" or ".cxx".
Fixes #540 reported by djack42.
2016-07-01: wsfulton
Fix corner case of wrapping std::vector of T pointers where a pointer to a pointer of T
also exists in the wrapped code. SF Bug 2359417 (967).
2016-06-26: wkalinin
[Java, C#] Patch #681 Fix seg fault when ignoring nested classes.
2016-06-25: mromberg
[Python] #711 Fix -castmode and conversion of signed and unsigned integer types.
See 2015-12-23 CHANGES entry for details of these improvements when they were
implemented for the default options (ie not using -castmode).
2016-06-25: ahnolds
Patch #730 - Fix %implicitconv for overloaded functions when using
-castmode or -fastdispatch options.
The result is that in all overload cases where there are multiple possibilities
with the same number of arguments, the dispatch function will first check for
exact (aka non implicit) matches, and then subsequently check for implicit
casting matches. This was already happening in the normal dispatch situation,
and in the -fastdispatch case two passes through the candidates were happening,
just with SWIG_POINTER_IMPLICIT_CONV always set. After this patch, it is not set
on the first pass, and then set on the second pass.
2016-06-25: liorgold
Patch #727 - Add support for C++11 type aliasing.
Version 3.0.10 (12 Jun 2016)
============================
2016-06-06: mromberg
[Python] Patch #698. Add support for -relativeimport for python 2.7, so -py3 is no
longer also required for relative import support.
2016-06-05: mromberg
[Python] Patch #694 - Fix package import regressions introduced in swig-3.0.9.
1) The code in 3.0.9 did not fall back to 'import _foo' if 'import bar._foo' failed
(assuming bar.foo was the main module). Every place _foo is imported now first tries
it from the package where foo was found and if that fails tries _foo as a global module.
2) The separate block of Python code that injected code to pull in the attributes
from _foo when -builtin is used made use of the -py3 switch to either do
'from ._foo import *' or "from _foo import *". This block of code no longer does this
and instead checks the Python version at runtime to switch between the two syntaxes.
In summary, swig-3.0.10 has been modified to ease the creation of wrapper modules
that can be fully made part of a Python package. SWIG no longer
assumes the dynamically linked C module is a global module.
The dynamic module can now be placed into either the same package as the pure Python
module or as a global module. Both locations are used by the Python wrapper to
locate the C module.
However, this could cause a backwards incompatibility with some code
that was relying on the ability of "from package import _module" to
pull attributes out of the package directly. If your code populates a
module (which is also a package) with attributes that are SWIG
generated modules which were not loaded in a conventional way,
swig-3.0.8 and earlier may have worked due to 'from package import
_module' bypassing a real import and pulling your module in as an
attribute. This will no longer work. Since this is not a common (or
even recommended) practice, most folk should not be affected.
*** POTENTIAL INCOMPATIBILITY ***
2016-05-31: wsfulton
Fix #690 - Smart pointer to %ignored class doesn't expose inherited methods.
Regression introduced in swig-3.0.9.
Version 3.0.9 (29 May 2016) Version 3.0.9 (29 May 2016)
=========================== ===========================
@ -135,7 +621,7 @@ Version 3.0.9 (29 May 2016)
2016-03-01: olly 2016-03-01: olly
Fix isfinite() check to work with GCC6. Fixes Fix isfinite() check to work with GCC6. Fixes
https://github.com/swig/swig/issues/615 reported by jplesnik. issue #615 reported by jplesnik.
2016-02-17: olly 2016-02-17: olly
[Python] Add missing keywords 'as' and 'with' to pythonkw.swg. [Python] Add missing keywords 'as' and 'with' to pythonkw.swg.
@ -192,7 +678,7 @@ Version 3.0.9 (29 May 2016)
2016-01-12: olly 2016-01-12: olly
[Javascript] For v8 >= 4.3.0, use V8_MAJOR_VERSION. [Javascript] For v8 >= 4.3.0, use V8_MAJOR_VERSION.
Fixes https://github.com/swig/swig/issues/561. Fixes issue 561.
2016-01-10: ahnolds 2016-01-10: ahnolds
Improved size_t and ptrdiff_t typemaps to support large values Improved size_t and ptrdiff_t typemaps to support large values
@ -783,7 +1269,7 @@ Version 3.0.3 (30 Dec 2014)
2014-10-21: wsfulton 2014-10-21: wsfulton
Fix issue #242 - Use of the "kwargs" feature no longer automatically turns on the Fix issue #242 - Use of the "kwargs" feature no longer automatically turns on the
"compactdefaultargs" feature if the target language does not support kwargs. "compactdefaultargs" feature if the target language does not support kwargs.
Only Java and Ruby support kwargs, so this affects all the other languages. This change affects all languages except Python and Ruby.
*** POTENTIAL INCOMPATIBILITY *** *** POTENTIAL INCOMPATIBILITY ***

View file

@ -1,7 +1,138 @@
Below are the changes for the current release. Below are the changes for the current release.
See the CHANGES file for changes in older releases. See the CHANGES file for changes in older releases.
See the RELEASENOTES file for a summary of changes in each release. See the RELEASENOTES file for a summary of changes in each release.
Issue # numbers mentioned below can be found on Github. For more details, add
the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 3.0.10 (in progress) Version 4.0.0 (in progress)
============================ ===========================
2017-06-03: wsfulton
Fix %import on a file containing a file scope %fragment forced inclusion to not
generate the fragment contents as %import should not result in code being generated.
The behaviour is now the same as importing code insertion blocks.
Wrapping FileC.i in the following example will result in no generated code, whereas
previously "#include <limits.h>" was generated:
// FileA.i
%fragment("<limits.h>", "header") %{
#include <limits.h>
%}
%{
#include <stdio.h>
%}
%fragment("<limits.h>");
// FileC.i
%import "FileA.i"
*** POTENTIAL INCOMPATIBILITY ***
2017-05-26: Volker Diels-Grabsch, vadz
[Java] #842 Extend from java.util.AbstractList<> and implement java.util.RandomAccess for
std::vector wrappers. This notably allows to iterate over wrapped vectors in a natural way.
2017-05-30: davidcl
[Scilab] #994 Undefined symbol error when loading in Scilab 6
2017-05-25: asibross
[Java] #370 #417 Missing smart pointer handling in Java director extra methods
swigReleaseOwnership() and swigTakeOwnership().
2017-05-23: wsfulton
[Java] #230 #759 Fix Java shared_ptr and directors for derived classes java compilation
error.
For shared_ptr proxy proxy classes, add a protected method swigSetCMemOwn for modifying
the swigCMemOwn and swigCMemOwnDerived member variables which are used by various other
methods for controlling memory ownership.
2017-05-21: Sghirate
[Java, C#, D] #449 Remove unnecessary use of dynamic_cast in directors to enable
non-RTTI compilation.
2017-05-21: wsfulton
[Python] #993 Fix handling of default -ve unsigned values, such as:
void f(unsigned = -1U);
2017-05-20: jschueller
[Python] #991 Fix E731 PEP8 warning: do not assign a lambda expression
2017-05-16: nihal95
[PHP] Add %pragma version directive to allow the version of the
extension to be set. Patch #970, fixes #360.
2017-05-13: yag00
Patch #975 - Add support for noexcept on director methods.
2017-04-27: redbrain
Issue #974, Patch #976 - Fix preprocessor handling of macros with commas in a comment.
2017-04-25: jleveque
[Lua] #959 - Fix Visual Studio C4244 conversion warnings in Lua wrappers.
2017-04-21: tamuratak
[Ruby] #964 - Add shared_ptr director typemaps.
2017-04-20: wsfulton
[Ruby] #586, #935 Add assert for invalid NULL type parameter when calling SWIG_Ruby_NewPointerObj.
2017-04-20: tamuratak
[Ruby] #930, #937 - Fix containers of std::shared_ptr.
Upcasting, const types (eg vector<shared_ptr<const T>>) and NULL/nullptr support added.
2017-04-12: smarchetto
[Scilab] New parameter targetversion to specify the Scilab target version (5, 6, ..) for code generation
With Scilab 6 target specified, identifier names truncation is disabled (no longer necessary)
2017-03-24: tamuratak
[Ruby] Fix #939 - Wrapping std::vector<bool> fix due to incorrect null checks
on VALUE obj.
2017-03-17: vadz
[C#] #947 Add support for std::complex<T>
2017-03-17: wsfulton
[Go] Fix handling of typedef'd function pointers and typedef'd member function pointers
such as:
typedef int (*FnPtr_td)(int, int);
int do_op(int x, int y, FnPtr_td op);
2017-03-16: wsfulton
Add support for member const function pointers such as:
int fn(short (Funcs::* parm)(bool)) const;
Also fix parsing of references/pointers and qualifiers to member
pointers such as:
int fn(short (Funcs::* const parm)(bool));
int fn(short (Funcs::* & parm)(bool));
2017-03-10: wsfulton
Extend C++11 alternate function syntax parsing to support const and noexcept, such as:
auto sum1(int x, int y) const -> int { return x + y; }
auto sum2(int x, int y) noexcept -> int { return x + y; }
2017-02-29: tamuratak
[Ruby] #917 - Add Enumerable module to all container class wrappers. It was missing
for std::list, std::multiset, std::unordered_multiset and std::unordered_map.
2017-02-27: assambar
[C++11] Extend parser to support throw specifier in combination
with override and/or final.
2017-02-10: tamuratak
[Ruby] #883 - Add support for C++11 hash tables:
std::unordered_map
std::unordered_set
std::unordered_multimap
std::unordered_multiset
2017-02-08: jcsharp
[C#] #887 Improve std::vector<T> wrapper constructors -
Replace constructor taking ICollection with IEnumerable and also add IEnumerable<T>
constructor to avoid the boxing and unboxing overhead of the original constructor,
when the type parameter is a value type.

View file

@ -1,788 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Unix)">
<META NAME="CREATED" CONTENT="20090712;16061100">
<META NAME="CHANGED" CONTENT="20090817;17311900">
<META NAME="Podatek 1" CONTENT="">
<META NAME="Podatek 2" CONTENT="">
<META NAME="Podatek 3" CONTENT="">
<META NAME="Podatek 4" CONTENT="">
<STYLE TYPE="text/css">
<!--
@page { margin: 2cm }
H1 { margin-bottom: 0.21cm }
H1.western { font-family: "Liberation Serif", serif }
H1.cjk { font-family: "DejaVu Sans" }
H1.ctl { font-family: "DejaVu Sans" }
P { margin-bottom: 0.21cm }
H2 { margin-bottom: 0.21cm }
A:link { so-language: zxx }
-->
</STYLE>
</HEAD>
<BODY LANG="en-US" DIR="LTR">
<H1 CLASS="western"><U>C++0x/C++11 support for SWIG</U></H1>
<H1 CLASS="western">Summary</H1>
<P>This is a technical overview of the C++0x/C++11 support for the Swig.
This area of Swig is a work in progress. Initial C++0x/C++11 support for
Swig was written during the Google Summer of Code 2009 period by
Matevž Jekovec.</P>
<H1 CLASS="western">SVN branch</H1>
<P>branches/gsoc2009-matevz</P>
<H1 CLASS="western">New C++11 features status</H1>
<P>Wikipedia article: <A HREF="http://en.wikipedia.org/wiki/C++0x">http://en.wikipedia.org/wiki/C%2B%2B0x</A>
</P>
<H2>Rvalue reference and move semantics [done]</H2>
<P>The Rvalues are used in practice to speed up the move operations
on different containers.</P>
<P>In the following example, we want to swap the given elements:</P>
<PRE>template &lt;class T&gt; swap(T&amp; a, T&amp; b) {
T tmp(a); // now we have two copies of a
a = b; // now we have two copies of b
b = tmp; // now we have two copies of tmp (aka a)
}</PRE><P>
This can now be solved using the new function std::move():</P>
<PRE>template &lt;class T&gt; swap(T&amp; a, T&amp; b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}</PRE><P STYLE="margin-bottom: 0cm">
For the move function to take effect, user needs to reimplement the
move constructor (taking ClassType&amp;&amp; as an argument) and
operator=(ClassType&amp;&amp;):</P>
<PRE>class MyClass {
MyClass(MyClass&amp;&amp; p) : ptr(p.ptr) {p.ptr = 0;}
MyClass&amp; operator=(MyClass&amp;&amp; p) {
std::swap(ptr, p.ptr);
return *this;
}
};</PRE><P>
In practice, the Rvalues are used for temporaries (when passing the
result of one function as an argument to another).</P>
<P>Done: Added type&amp;&amp; to Swig parser. Added testcase
cpp11_rvalue_reference.i. Operator &amp;&amp; is treated the same as
operator &amp;. R11450</P>
<P STYLE="margin-bottom: 0cm">Article:
<A HREF="http://www.artima.com/cppsource/rvalue.html">http://www.artima.com/cppsource/rvalue.html</A></P>
<H2>Generalized constant expressions [done]</H2>
<P>In C++11 you can define functions as constant expressions.
Functions need to return constant value in form &quot;return expr&quot;,
where expr is a constant expression.
</P>
<P>A keyword &quot;constexpr&quot; is introduced for this. eg.:
constexpr int getNumber() { return 5; } const int MY_CONSTANT =
getNumber();
</P>
<P>Constants are treated as normal variables in interpreted languages
because they are not compiled into the executable. Java &quot;final&quot;
constants are defined runtime as well. C++ constants need to be
declared in the header file and defined in the implementation file,
so swig doesn't need to know about the constant values when parsing
the header file.
</P>
<P>Done: Added the “constexpr “ keyword to Swig. Added testcase
cpp11_constexpr. R11322</P>
<P>Problem: No compilers were known to support constexpr yet, so the
testcase was temporarily commented out in common.mk.
</P>
<H2>Extern template [done]</H2>
<P>Extern template forces the GCC compiler to not instantiate the
template in the translation unit at that time. It's a feature
specifically aimed at compilers to speed up the compilation process.
</P>
<P>Done: Added support for 'extern template class
std::vector&lt;MyClass&gt;;'. Added testcase cpp11_template_explicit.
R11385 , R11386</P>
<H2>Initializer lists [done]</H2>
<P>Initializer list is a new type in standard library:
std::initializer_list&lt;T&gt;. New symbols {} are introduced for the
initializer lists.
</P>
<P>One can now use:
</P>
<PRE> class A {
public:
A( std::initializer_list&lt;int&gt; );
};
A a1 = {1,2,3,4};</PRE><P>
Languages like Java, C# and Python already support direct creation of
lists natively.</P>
<P>Problem: initializer_list cannot be treated as an ordinary list.
The constructor containing initializer_list can only be accessed by
assigning the value using the {} brackets. I also don't think there
is a simple way to convert an ordinary list or a vector to the
initializer_list.</P>
<P>Done: Ignored the constructor having initializer_list as its
argument. Show warning to the user. Added testcase
cpp11_initializer_list. R11450</P>
<P>Article:
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1919.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1919.pdf</A></P>
<H2>Uniform initialization [done]</H2>
<P>The new C++11 standard will allow the following:</P>
<PRE>struct IdString {
std::string name;
int identifier;
};
IdString GetString() {
return {&quot;SomeName&quot;, 4}; //Note the lack of explicit type.
}</PRE><P>
The feature works exactly as it did now for POD types only (eg. int
a[] = {1,2,3};). The following declarations are the same in the new
C++11:</P>
<PRE>IdString str1 = {„SomeName“, 4};
IdString str2{„SomeName“, 4};</PRE><P>
The new way of using uniform initialization allows the following:</P>
<PRE>struct BasicStruct {
int x;
double y;
};
struct AltStruct {
AltStruct(int x, double y) : x_{x}, y_{y} {}
private:
int x_;
double y_;
};
BasicStruct var1{5, 3.2}; // only fills the struct components
AltStruct var2{2, 4.3}; // calls the constructor</PRE><P>
The new syntax is specific to C++. Java, C# and scripting languages
do not support this behaviour, but always need constructors. They
support {} brackets for declaration of arrays as C does + they add
support for creation of arrays on-the-fly (what C++11 introduced with
this feature and more).</P>
<P>Done: Added syntax for {} member initialization in class
constructor. Added testcase cpp11_uniform_initialization. R11413</P>
<H2>Type inference [partially done]</H2>
<P>A new keyword 'auto' is introduced in C++11:</P>
<PRE>auto a1 = 100;
auto a2 = myFunc();</PRE><P>
The type of a1 and a2 is automatically determined according to the
initialization value during the semantic phase of the compiler.</P>
<P>Another macro 'decltype()' is introduced. The macro takes the
concrete object as an argument and returns its type. User could use
this as:</P>
<PRE>int i = 100;
decltype(i) j = 200; // decltype(i) = int</PRE><P STYLE="margin-bottom: 0cm">
Calling operators are allowed as well:</P>
<PRE STYLE="margin-bottom: 0.5cm">decltype(i+j) k = 300;</PRE><P>
Done: Added support for decltype() syntax. Test cases for normal
decltype members and alternate function members work fine. Currently
only syntax in form decltype(variable name) work. No support for
custom expresions eg. decltype(i+j) yet. R11525</P>
<P>TODO: William proposed to support the hidden variables as well
(ones not parsed by Swig and added to symbol table). This also allows
Swig to parse custom expressions like decltype(i+j). The idea is to
introduce a new SwigType for this.</P>
<H2>Range-based for-loop [ignored]</H2>
<P>This feature is always present inside the implementation block
only.
</P>
<H2>Lambda functions and expressions [done]</H2>
<P>C++11 introduces lambda functions defined as:</P>
<PRE STYLE="margin-bottom: 0.5cm">[](int x, int y) -&gt; int { return x + y; }</PRE><P>
If the lambda function contains a single return statement only or the
function doesn't return any type, the return type '-&gt;' can be
omitted. Lambda functions are function objects.</P>
<P>The following example prints the number of items stored in a list:</P>
<PRE>std::vector&lt;int&gt; someList;
int total = 0;
std::for_each( someList.begin(), someList.end(), [&amp;total](int x) {total += x} );
std::cout &lt;&lt; total;</PRE><P>
Parameters inside the [] are the visible parameters of the lambda
functions. These can be &amp; (references), = (copies), variable name
(variable copy), &amp;variable name (variable reference) or this
(copy of the current object).</P>
<P>Lambda functions can be stored using:</P>
<PRE STYLE="margin-bottom: 0.5cm">auto myLambdaFunc = [this]() { this-&gt;SomePrivateMemberFunction() };</PRE><P>
Proposal: Lambda functions are most commonly used inside the function
block to quickly define how the sort, find and similar functions
should work (the other way would be overriding a class – the Java
style). The latest GCC does not support lambda functions yet so it is
difficult to test the feature once implemented. I would implement the
syntax support for this feature, but produce no wrapper code. Lambda
functions still work inside the function block though.</P>
<P>Article:
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf</A></P>
<P>Done: Added syntax support for the lambda functions. Added
testcase cpp11_lambda_functions.i. R11491, R11492</P>
<H2>Alternate function syntax [done]</H2>
<P>The problem with decltype() is that the parameters need to be
defined before the decltype. The following syntax is not valid,
because lhs and rhs hasn't been defined at the time of decltype:</P>
<PRE>template&lt; typename LHS, typename RHS&gt;
decltype(lhs+rhs) AddingFunc(const LHS &amp;lhs, const RHS &amp;rhs) {return lhs + rhs;} //Not legal C++11</PRE><P>
The solution C++11 offers is the combination of the 'auto' keyword
before and '-&gt; rettype' after the function declaration:</P>
<PRE>template&lt; typename LHS, typename RHS&gt;
auto AddingFunc(const LHS &amp;lhs, const RHS &amp;rhs) -&gt; decltype(lhs+rhs) {return lhs + rhs;}</PRE><P>
The new syntax only makes the job for the C++ compilers easier when
parsing such functions. The new syntax can be used for ordinary
functions as well:</P>
<PRE>struct SomeStruct {
auto FuncName(int x, int y) -&gt; int;
};
auto SomeStruct::FuncName(int x, int y) -&gt; int {
return x + y;
}</PRE><P>
Done: Added support for the 'auto' return type. Added support for the
'-&gt; type' after the funtion declaration. Added testcases
cpp11_alternate_function_syntax.i and
cpp11_alternate_function_syntax_runme.py. R11414</P>
<H2>Concepts, Axioms [ignored]</H2>
<P>In C++ there is a common problem when you use a template in the
class which doesn't support all the operations the functions in the
class actually do on the type. Compiler errors are usually very long
and unreadable. C++11 adds support for the &quot;concepts&quot;. The
idea is to define what operations and attributes should the template
have. In contrast to class inheritance and polimorphism, all lookups
are done in compile-time.
</P>
<P>Basic syntax (note LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&amp;id=LessThanComparable">?</A>
instead of &quot;class&quot; or &quot;typename&quot;):
</P>
<PRE> template&lt;LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&amp;id=LessThanComparable">?</A> T&gt;
const T&amp; min(const T &amp;x, const T &amp;y) {
return y &lt; x ? y : x;
}</PRE><P>
Extended syntax (requires conditions are separated with &amp;&amp;,
|| or !):
</P>
<PRE> template&lt; typename T&gt; requires LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&amp;id=LessThanComparable">?</A>&lt;T&gt;
const T&amp; min(const T &amp;x, const T &amp;y) {
return y &lt; x ? y : x;
}</PRE><P>
Definition of the concepts:
</P>
<PRE> concept LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&amp;id=LessThanComparable">?</A>&lt; typename T &gt; {
bool operator&lt;(T,T);
requires GreaterThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&amp;id=GreaterThanComparable">?</A>&lt;T&gt;;
typename value_type;
typename reference;
};</PRE><P>
Concept maps allow usage of a specific type:
</P>
<PRE> template&lt; typename T&gt;
concept_map InputIterator<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&amp;id=InputIterator">?</A>&lt;T*&gt; {
typedef T value_type ;
typedef T&amp; reference ;
typedef T* pointer ;
typedef std::ptrdiff_t difference_type ;
};</PRE><P>
Concept maps can act as mini-types, with function definitions and
other constructs commonly associated with classes:
</P>
<PRE> concept Stack&lt; typename X&gt; {
typename value_type;
void push(X&amp;, const value_type&amp;);
void pop(X&amp;);
value_type top(const X&amp;);
bool empty(const X&amp;);
};
template&lt; typename T&gt;
concept_map Stack&lt;std::vector&lt;T&gt; &gt; {
typedef T value_type;
void push(std::vector&lt;T&gt;&amp; v, const T&amp; x) { v.push_back(x); }
void pop(std::vector&lt;T&gt;&amp; v) { v.pop_back(); }
T top(const std::vector&lt;T&gt;&amp; v) { return v.back(); }
bool empty(const std::vector&lt;T&gt;&amp; v) { return v.empty(); }
};</PRE><P>
Axioms are a facility pertaining to concepts supplied by C++11 to
express the semantic properties of concepts. For example, the concept
Semigroup can be defined with an axiom Associativity as:
</P>
<PRE> concept Semigroup&lt; typename Op, typename T&gt; : CopyConstructible<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&amp;id=CopyConstructible">?</A>&lt;T&gt; {
T operator()(Op, T, T);
axiom Associativity(Op op, T x, T y, T z) {
op(x, op(y, z)) == op(op(x, y), z);
}
};</PRE><P>
Axioms are more like hints to the compiler to speed-up the process of
compilation.
</P>
<P>Ignored: Concepts and axioms were removed from the C++11 standard.
</P>
<H2>Object construction improvement [done]</H2>
<P>This feature allows classes constructors to call other
constructors with different arguments (similar to Java and C#
behaviour).
</P>
<P>The syntax is as follows:
</P>
<PRE> class SomeType {
int number;
public:
SomeType(int newNumber) : number(newNumber) {}
SomeType() : SomeType(42) {}
};</PRE><P>
Also when using the inheritance, the feature introduces inheritance
of all superclass constructors without being defined separately in
the inherited class:
</P>
<PRE> class BaseClass {
public:
BaseClass(int iValue);
};
class DerivedClass: public BaseClass {
public:
using BaseClass::BaseClass; // Adds DerivedClass(int) constructor
};</PRE><P>
Swig already correctly parses and produces the correct wrapper for
the “using” keyword.</P>
<P>Done: Added testcase cpp11_constructors.i which covers both
constructor delegation and constructor inheritance. R11532</P>
<P>Problem: Constructor delegation and constructor inheritance is not
supported by any compiler yet, so it's impossible to try and test
this feature.</P>
<H2>Null pointer constant [done]</H2>
<P>nullptr is part of the standard library.
</P>
<P>It's defined as typedef decltype(nullptr) nullptr_t;
</P>
<P>nullptr_t is defined in &lt;cstddef&gt;.
</P>
<P>As far as the C++ is compatible with 0 as the pointer value, swig
values will work for the C++. And the other way around, nullptr
behaves as the ordinary pointer (false, if empty, true, if not
empty), so it's ok for swig to compare it.</P>
<P>Done: Written a testcase cpp11_null_pointer_constant.i and
cpp11_null_pointer_constant_runme.py to prove the nullptr
functionality. R11484</P>
<H2>Strongly typed enumerations [partially done]</H2>
<P>C++11 introduces a new syntax for strongly typed enum declaration:
</P>
<PRE> enum class Enumeration {
Val1,
Val2,
Val3 = 100,
Val4 /* = 101 */
};</PRE><P>
Typing if (Val4 == 101) will result in compilation error.
</P>
<P>The enum itself can now be explicitely of type int, long, unsigned
int etc.:
</P>
<PRE STYLE="margin-bottom: 0.5cm"> enum class Enum2 : unsigned int {Val1, Val2};</PRE><P>
And it can be forward declared as well:
</P>
<PRE> enum Enum1; //Illegal in C++ and C++11; no size is explicitly specified.
enum Enum2 : unsigned int; //Legal in C++11.
enum class Enum3; //Legal in C++11, because enum class declarations have a default type of &quot;int&quot;.
enum class Enum4: unsigned int; //Legal C++11.
enum Enum2 : unsigned short; //Illegal in C++11, because Enum2 was previously declared with a different type.</PRE><P>
Done: Added syntax 'enum class Name' and forward declarators 'enum
Name : inherited type' or 'enum class Name : inherited type' in
R11449.</P>
<P>TODO: Add semantic support for enum elements not clashing with
enum elements in other enum classes. See cpp11_strongly_typed_enums.i
warnings.</P>
<P>Problem: Swig currently doesn't support nested classes. This
feature should be implemented using a new nested class when using
“enum class” with a single anonymous “enum {elements}”
element inside. For example:</P>
<PRE STYLE="margin-bottom: 0.5cm">class A { enum class EA { a,b,c,d }; };</PRE><P>
should be mapped to</P>
<PRE STYLE="margin-bottom: 0.5cm">class A { class EA { enum {a,b,c,d}; }; };</PRE><H2>
Angle bracket [done]</H2>
<P>Support for right angled brackets was implemented using the
following article as a base:
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html</A>
</P>
<P>Done: Added support for angle brackets. Used the preferred
&quot;Approach 1&quot;. Added a testcase named
cpp11_template_double_brackets. R11245</P>
<H2>Explicit conversion operators [done]</H2>
<P>This is used when converting one type to another (eg. if
(myObject) {}, where myObject is your custom class converted to
bool).
</P>
<P>Requires both operator and function overloading which is not
supported in any target language (eg. python, php).
</P>
<P>Done: Swig already supports the keyword &quot;explicit&quot; for
function types as well. Added test case
cpp11_explicit_conversion_operators. R11323</P>
<H2>Template typedefs [partially done]</H2>
<P>The new C++11 will allow creation of wrapper around the template.
For example, if we want to do this:</P>
<PRE>template&lt; typename first, typename second, int third&gt;
class SomeType;
template&lt; typename second&gt;
typedef SomeType&lt;OtherType, second, 5&gt; TypedefName; //Illegal in C++</PRE><P>
This is still illegal! But we can now use the new syntax for
achieving the same effect:</P>
<PRE>template&lt; typename first, typename second, int third&gt;
class SomeType;
template&lt; typename second&gt;
using TypedefName = SomeType&lt;OtherType, second, 5&gt;;</PRE><P>
Here we created a new wrapper TypedefName taking one template
argument &lt;second&gt; which creates a type SomeType&lt;OtherType,
second, 5&gt;. OtherType and 5 are predefined here and hidden from
the user – the user only uses TypedefName type.</P>
<P>The same goes for the following example:</P>
<PRE>typedef void (*PFD)(double); // Old style
using PF = void (*)(double); // New introduced syntax</PRE><P>
Swig supports parsing typedefs for templates as well for example:</P>
<PRE STYLE="margin-bottom: 0.5cm">typedef List&lt;int&gt; intList;</PRE><P>
Done: Expanded support for the new 'using' syntax and template
aliasing. Added testcase cpp11_template_typedefs. R11533</P>
<P>TODO: Make Swig aware of the newly defined typedef. The TYPEDEF
keyword is part of the storage_class rule and type+declarator (see
c_decl rule) is the right part of the definition – for example void
(*PFD)(double) cannot be transformed to void *(double) easily. To
fully support the new 'using' form, we'll probably have to change the
type, type_right rules and declarator, direct_declarator,
notso_direct_declarator etc., which is PITA.</P>
<H2>Unrestricted unions [done]</H2>
<P>C++ currently offers usage of unions for types with trivial
constructors only. The new C++11 standard allows usage of types with
non-trivial constructors as well:</P>
<PRE> struct point {
point() {}
point(int x, int y): x_(x), y_(y) {}
int x_, y_;
};
union P {
int z;
double w;
point p; // Illegal in C++; point has a non-trivial constructor. However, this is legal in C++11.
} p1;</PRE><P>
Swig already parses the given syntax.</P>
<P>Done: Added testcase cpp11_unrestricted_unions. R11435, R11447</P>
<P>Problem: GCC doesn't support unrestricted unions yet so there is
no way to actually test, if it works.</P>
<H2>Variadic templates [partially done]</H2>
<P>The new C++11 offers the following syntax:</P>
<PRE STYLE="margin-bottom: 0.5cm">template&lt;typename... Values&gt; class tuple;</PRE><P>
This can be used for example:</P>
<PRE STYLE="margin-bottom: 0.5cm">class tuple&lt;int, std::vector&lt;int&gt;, std::map&lt;std::string, std::vector&lt;int&gt;&gt;&gt; someInstanceName;</PRE><P>
The ... is used in two cases. One is in the template header where it
marks on the left the keywords 'typename' or 'class' and a type name
on the right. The second case is usually in the function block to
decompose typename on the left of the ... . For example:</P>
<PRE>void printf(const char *s) {
while (*s) {
if (*s == '%' &amp;&amp; *(++s) != '%')
throw std::runtime_error(&quot;invalid format string: missing arguments&quot;);
std::cout &lt;&lt; *s++;
}
}
template&lt;typename T, typename... Args&gt;
void printf(const char* s, T value, Args... args) { // recursive action – split previous args to value + args
while (*s) {
if (*s == '%' &amp;&amp; *(++s) != '%') {
std::cout &lt;&lt; value;
printf(*s ? ++s : s, args...); // call even when *s == 0 to detect extra arguments
return;
}
std::cout &lt;&lt; *s++;
}
throw std::logic_error(&quot;extra arguments provided to printf&quot;);
}</PRE><P>
The tricky part is that variadic templates can unpack actually
anywhere – including the class inheritance :(</P>
<PRE>template &lt;typename... BaseClasses&gt; class ClassName : public BaseClasses... {
public:
ClassName (BaseClasses&amp;&amp;... baseClasses) : BaseClasses(baseClasses)... {}
}</PRE><P>
A new extension to sizeof is also introduced with this feature. The
... after sizeof returns number of arguments:</P>
<PRE>template&lt;typename ...Args&gt; struct SomeStruct {
static const int size = sizeof...(Args);
}
// SomeStruct&lt;Type1, Type2&gt;::size is 2 and SomeStruct&lt;&gt;::size is 0</PRE><P>
Done: Added syntax support for 'typename' or 'class' + ... + id.
Added testcase cpp11_variadic_templates. R11458</P>
<P>Done: Added syntax support for BaseClass + ..., type + ... + id in
parameters and baseclass + ... for intializers after constructor.
Extended Swig syntax to support sizeof...(Args). R11467</P>
<P>Done: Fixed %template to support variadic number of templates.</P>
<P>TODO: Only (if present) first variadically defined argument is
currently used in %template directive. The next ones are ignored.</P>
<H2>New string literals [partially done]</H2>
<P>Beside the implementation, the new C++11 Unicode and custom
delimeter constants can occur in templates in the header file.
</P>
<P>Done: Added symbols 'u', 'u8' and 'U' to mark the beginning of the
UTF string. Also added test case cpp11_raw_string_literals. R11327</P>
<P>Done: Added R&quot;DELIMITER[, ]DELIMITER&quot; for a custom
delimiter for the beginning/end of the string. R11328</P>
<P>TODO: Fix the Swig's C++ preprocessor bug when parsing an odd
number of “ inside the string brackets. See
Source/Preprocessor/cpp.c.</P>
<H2>User-defined literals [partially done]</H2>
<P>C++ has different suffix literals. eg. 12.5f marks the number 12.5
as float.
</P>
<P>C++11 allows user to define his own suffix for the strings always
starting with the underscore (_). eg. int a = &quot;hello&quot;_mySuffix;
</P>
<P>The syntax is similar to other operator overloading functions:
</P>
<PRE STYLE="margin-bottom: 0.5cm"> OutputType operator &quot;&quot; _mySuffix(const char * string_values);</PRE><P>
The null terminated const char* is the string between the &quot;&quot;.
The _mySuffix is the name of the suffix operator. And the OutputType
is the outputType the operator returns.
</P>
<P>Other forms are:
</P>
<PRE> OutputType operator &quot;&quot; _mySuffix(const char * string_values, size_t num_chars);
OutputType operator &quot;&quot; _mySuffix(const wchar_t * string_values, size_t num_chars);
OutputType operator &quot;&quot; _mySuffix(const char16_t * string_values, size_t num_chars);
OutputType operator &quot;&quot; _mySuffix(const char32_t * string_values, size_t num_chars);
OutputType operator &quot;&quot; _mySuffix(int value); /* cooked version - ie. atoi() of string */</PRE><P>
Another possibility is to use variadic templates:
</P>
<PRE> template&lt;char...&gt; OutputType operator &quot;&quot; _mySuffix();
OutputType someVariable = &quot;1234&quot;_mySuffix;</PRE><P>
This instantiates the literal processing function as
operator&quot;&quot;_Suffix&lt;'1', '2', '3', '4'&gt;. In this form,
there is no terminating null character to the string. The main
purpose to doing this is to use C++11's constexpr keyword and the
compiler to allow the literal to be transformed entirely at compile
time, assuming OutputType is a constexpr-constructable and copyable
type, and the literal processing function is a constexpr function.</P>
<P>Article:
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf</A></P>
<P>Done: Added syntax support for userdefined literals. Added
testcase cpp11_userdefined_literals.i. R11494</P>
<P>TODO: %rename doesn't parse operator”” yet.</P>
<H2>Thread-local storage [done]
</H2>
<P>New C++11 introduces keyword &quot;thread_local&quot; which marks
the following variable dynamically located depending on the current
thread when using the address-of (&amp;) operator.
</P>
<P>Syntax:
</P>
<PRE> struct A {
thread_local int val;
};</PRE><P>
Done: Add &quot;thread_local&quot; keyword to Swig. Added testcase
cpp11_thread_local. R11393</P>
<H2>Defaulting/deleting of standard functions on C++ objects [done]</H2>
<P>C++ automatically creates default constructor with empty
parameters, copy constructor, operator= and destructor for any class.
Sometimes user wants to explicitly remove one of them or enable them
(eg. default constructor with empty parameters doesn't work any more,
if any other constructor is defined).
</P>
<P>Words &quot;default&quot; and &quot;delete&quot; are introduced.
The syntax is similar to declaration of pure virtual function:
</P>
<PRE> struct NonCopyable {
NonCopyable &amp; operator=(const NonCopyable&amp;) = delete; /* Removes operator= */
NonCopyable(const NonCopyable&amp;) = delete; /* Removed copy constructor */
NonCopyable() = default; /* Explicitly allows the empty constructor */
void *operator new(std::size_t) = delete; /* Removes new NonCopyable */
};</PRE><P>
User has the ability by using keyword delete to disallow calling of
the standard functions brought by C++ itself.
</P>
<PRE> struct A1 {
void f(int i);
void f(double i) = delete; /* Don't cast double to int. Compiler returns an error */
};
struct A2 {
void f(int i);
template&lt;class T&gt; void f(T) = delete; /* Only accept int */
};</PRE><P>
Ignored: Swig already parses the keywords &quot;= delete&quot; and &quot;=
default&quot;. These keywords are used for built-in functions (copy
constructor, operator= etc.), which are ignored by Swig anyway.</P>
<P>Done: Added testcase cpp11_default_delete. R11535</P>
<H2>Type long long int [done]</H2>
<P>Type long long int is an integer type that has at least 64 useful
bits. C99 added it to its standard, but the C++ didn't adopt it until
C++11. Most C++ compilers supported it though.
</P>
<P>Done: Swig already parses the C code including the long long type.
</P>
<H2>Static assertions [done]</H2>
<P>static_assert() can be used at class scope as well eg.:
</P>
<PRE> template &lt;typename T&gt;
struct Check {
static_assert(sizeof(int) &lt;= sizeof(T), &quot;not big enough&quot;);
};</PRE><P>
Done: Added syntax support for &quot;static_assert()&quot;. Added
test case cpp11_static_assert. R11369</P>
<H2>Allow sizeof to work on members of classes without an explicit
object [done]</H2>
<P>C++11 allows calls of sizeof to concrete objects as well:
</P>
<PRE> struct A { int member; };
sizeof(A::member); //Does not work with C++03. Okay with C++11</PRE><P>
This kind of syntax is already supported by Swig.</P>
<P>Done: Added testcase cpp11_sizeof_objects. R11538
</P>
<H2>Threading facilities [ignored]</H2>
<P>C++11 will add the following classes to the standard library:
</P>
<PRE> * std::thread
* std::mutex, std::recursive_mutex
* std::condition_variable, std::condition_variable_any
* std::lock_guard, std::unique_lock
* std::packaged_task</PRE><P>
Ignored: No changes to the language itself is made.
</P>
<H2>Tuple types [TODO]</H2>
<P>Tuple is array of various types. C++11 introduced this feature
using variadic templates. Tuple is defined as:</P>
<PRE STYLE="margin-bottom: 0.5cm">template &lt;class ...Types&gt; class tuple;</PRE><P>
Constructor is automatically generated filling the tuple elements.
get&lt;X&gt; function is introduced to get the Xth element in the
tuple.</P>
<PRE>typedef tuple&lt; int, double, long &amp;, const char * &gt; test_tuple ;
long lengthy = 12 ;
test_tuple proof( 18, 6.5, lengthy, &quot;Ciao!&quot; ) ;
lengthy = get&lt;0&gt;(proof) ; // Assign to 'lengthy' the value 18.
get&lt;3&gt;(proof) = &quot; Beautiful!&quot; ; // Modify the tuple’s fourth element.</PRE><P>
Tuples can be copied to each other, if all the elements are copiable:</P>
<PRE>typedef tuple&lt; int , double, string &gt; tuple_1 t1 ;
typedef tuple&lt; char, short , const char * &gt; tuple_2 t2( 'X', 2, &quot;Hola!&quot; ) ;
t1 = t2 ; // Ok, first two elements can be converted,
// the third one can be constructed from a 'const char *'.</PRE><P>
TODO: Implement wrappers for the tuplet&lt;&gt; class.</P>
<H2>Hash tables [TODO]</H2>
<P>C++11 introduces the &quot;unordered&quot; version of existing
types, which in practice work faster than the linear types:
</P>
<PRE> - unordered set
- unordered multiset
- unordered map
- unordered multimap</PRE><P>
Swig should use the &quot;unordered&quot; types exactly the same as
the original linear types.</P>
<P>Problem: Unordered types do not contain exactly same members as
ordered ones (eg. _Hashtable_iterator does not offer operator--() and
constructor with compare function which is required). So simply
aliasing unordered classes to ordered ones doesn't work.</P>
<P>TODO: Implement wrappers for unordered_ types. Initial work is
already done in Lib/std/unordered_*.i files.</P>
<H2>Regular expressions [ignored]</H2>
<P>Two new classes are introduced in C++11: basic_regex and
match_results. Both are defined in regex header file.
</P>
<P>Ignored: The new feature extends the standardy library only. No
changes to Swig needed.
</P>
<H2>General-purpose smart pointers [done]</H2>
<P>This feature deprecates auto_ptr and adds shared_ptr, weak_ptr and
unique_ptr to the standard library.
</P>
<P>This feature only adds the smart pointers to the standard library
and doesn't effect the C++ syntax.</P>
<P>Done: Added test case which uses all three smart pointers in the
class. R11394</P>
<P>Problem: GCC standard library doesn't contain the new smart
pointers yet.
</P>
<H2>Extensible random number facility [ignored]</H2>
<P>This feature standardize the pseudo random number algorithm
(currently, the random number generator was dependent on the
platform/compiler). It adds functions linear_congruential,
subtract_with_carry and mersenne_twister and symbols
uniform_int_distribution, bernoulli_distribution,
geometric_distribution, poisson_distribution, binomial_distribution,
uniform_real_distribution, exponential_distribution,
normal_distribution and gamma_distribution to the standard library.
</P>
<P>Ignored: The new feature extends the standardy library only. No
changes to Swig needed.
</P>
<H2>Wrapper reference [ignored]</H2>
<P>This feature adds ref and cref classes to the standard library
(#include &lt;utility&gt;) usually used in tempalte functions.
</P>
<P>Ignored: The new feature extends the standardy library only. No
changes to Swig needed.
</P>
<H2>Polymorphous wrappers for function objects [done]</H2>
<P>Two features are introduced:
</P>
<UL>
<LI><P>The function template wrapper:
</P>
</UL>
<PRE STYLE="margin-bottom: 0.5cm"> function&lt;int ( int, int )&gt; pF;</PRE>
<UL>
<LI><P>and the function object:
</P>
</UL>
<PRE> struct Test {
bool operator()( short x, short y );
};</PRE><P>
Swig already supports the two.</P>
<P>Done: Added a runtime testcase for function objects
cpp11_function_objects. R11419.</P>
<H2>Type traits for metaprogramming [ignored]</H2>
<P>C++11 adds a new header file &lt;type_traits&gt; which includes
helper functions to determine the template type while initializing
the object at compile time.
</P>
<P>Swig already supports the following code:
</P>
<PRE> template&lt; int B, int N &gt;
struct Pow {
// recursive call and recombination.
enum{ value = B*Pow&lt; B, N-1 &gt;::value };
};
template&lt; int B &gt; struct Pow&lt; B, 0 &gt; // <EM>N == 0</EM> condition of termination.
{
enum{ value = 1 };
};
int quartic_of_three = Pow&lt; 3, 4 &gt;::value ;</PRE><P>
Functions is_convertible, is_integral, is_integral_const etc. are
part of the new header:
</P>
<PRE>// First way of operating.
template&lt; bool B &gt; struct algorithm {
template&lt; class T1, class T2 &gt; int do_it( T1 &amp;, T2 &amp; ) { /*...*/ }
};
// Second way of operating.
template&lt;&gt; struct algorithm&lt;true&gt; {
template&lt; class T1, class T2 &gt; int do_it( T1, T2 ) { /*...*/ }
};
// Instantiating 'elaborate' will automatically instantiate the correct way to operate.
template&lt; class T1, class T2 &gt; int elaborate( T1 A, T2 B ) {
// Use the second way only if 'T1' is an integer and if 'T2' is
// in floating point, otherwise use the first way.
return algorithm&lt; is_integral&lt;T1&gt;::value &amp;&amp; is_floating_point&lt;T2&gt;::value &gt;::do_it( A, B );
}</PRE><P>
Swig correctly parses the syntax for template&lt;bool&gt;,
template&lt;class T&gt; and template&lt;&gt;.
</P>
<P>Ignored: Swig requires explicitly defined template class
(%template directive) to export it to the target language.</P>
<H2>Uniform method for computing return type of function objects
[partially done]</H2>
<P>The template function is introduced: std::result_of() which
depends on decltype:
</P>
<PRE>template&lt; class Obj &gt;
class calculus_ver2 {
public:
template&lt; class Arg &gt;
typename std::result_of&lt;Obj(Arg)&gt;::type operator()( Arg&amp; a ) const {
return member(a);
}
private:
Obj member;
};</PRE><P>
Swig correctly parses the result_of class.</P>
<P>TODO: The return type (the result_of::type member) is not
calculated by Swig. This needs a much more complex semantic parser.</P>
<P>Done: Added testcase cpp11_result_of. R11534</P>
</BODY>
</HTML>

View file

@ -29,7 +29,7 @@
<li><a href="#CPlusPlus11_strongly_typed_enumerations">Strongly typed enumerations</a> <li><a href="#CPlusPlus11_strongly_typed_enumerations">Strongly typed enumerations</a>
<li><a href="#CPlusPlus11_double_angle_brackets">Double angle brackets</a> <li><a href="#CPlusPlus11_double_angle_brackets">Double angle brackets</a>
<li><a href="#CPlusPlus11_explicit_conversion_operators">Explicit conversion operators</a> <li><a href="#CPlusPlus11_explicit_conversion_operators">Explicit conversion operators</a>
<li><a href="#CPlusPlus11_alias_templates">Alias templates</a> <li><a href="#CPlusPlus11_alias_templates">Type alias and alias templates</a>
<li><a href="#CPlusPlus11_unrestricted_unions">Unrestricted unions</a> <li><a href="#CPlusPlus11_unrestricted_unions">Unrestricted unions</a>
<li><a href="#CPlusPlus11_variadic_templates">Variadic templates</a> <li><a href="#CPlusPlus11_variadic_templates">Variadic templates</a>
<li><a href="#CPlusPlus11_new_string_literals">New string literals</a> <li><a href="#CPlusPlus11_new_string_literals">New string literals</a>
@ -52,7 +52,7 @@
<li><a href="#CPlusPlus11_general_purpose_smart_pointers">General-purpose smart pointers</a> <li><a href="#CPlusPlus11_general_purpose_smart_pointers">General-purpose smart pointers</a>
<li><a href="#CPlusPlus11_extensible_random_number_facility">Extensible random number facility</a> <li><a href="#CPlusPlus11_extensible_random_number_facility">Extensible random number facility</a>
<li><a href="#CPlusPlus11_wrapper_reference">Wrapper reference</a> <li><a href="#CPlusPlus11_wrapper_reference">Wrapper reference</a>
<li><a href="#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphous wrappers for function objects</a> <li><a href="#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphic wrappers for function objects</a>
<li><a href="#CPlusPlus11_type_traits_for_metaprogramming">Type traits for metaprogramming</a> <li><a href="#CPlusPlus11_type_traits_for_metaprogramming">Type traits for metaprogramming</a>
<li><a href="#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">Uniform method for computing return type of function objects</a> <li><a href="#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">Uniform method for computing return type of function objects</a>
</ul> </ul>
@ -603,37 +603,11 @@ Conversion operators either with or without <tt>explicit</tt> need renaming to a
them available as a normal proxy method. them available as a normal proxy method.
</p> </p>
<H3><a name="CPlusPlus11_alias_templates">7.2.16 Alias templates</a></H3> <H3><a name="CPlusPlus11_alias_templates">7.2.16 Type alias and alias templates</a></H3>
<p> <p>
The following is an example of an alias template: A type alias is a statement of the form:
<div class="code"><pre>
template&lt; typename T1, typename T2, int &gt;
class SomeType {
public:
T1 a;
T2 b;
int c;
};
template&lt; typename T2 &gt;
using TypedefName = SomeType&lt;char*, T2, 5&gt;;
</pre></div>
<p>
These are partially supported as SWIG will parse these and identify them, however, they are ignored as they are not added to the type system. A warning such as the following is issued:
</p>
<div class="shell">
<pre>
example.i:13: Warning 342: The 'using' keyword in template aliasing is not fully supported yet.
</pre>
</div>
<p>
Similarly for non-template type aliasing:
</p> </p>
<div class="code"><pre> <div class="code"><pre>
@ -641,22 +615,43 @@ using PFD = void (*)(double); // New introduced syntax
</pre></div> </pre></div>
<p> <p>
A warning will be issued: which is equivalent to the old style typedef:
</p> </p>
<div class="shell">
<pre>
example.i:17: Warning 341: The 'using' keyword in type aliasing is not fully supported yet.
</pre>
</div>
<p>The equivalent old style typedefs can be used as a workaround:</p>
<div class="code"><pre> <div class="code"><pre>
typedef void (*PFD)(double); // The old style typedef void (*PFD)(double); // The old style
</pre></div> </pre></div>
<p>
The following is an example of an alias template:
<div class="code"><pre>
template&lt; typename T1, typename T2, int N &gt;
class SomeType {
public:
T1 a;
T2 b;
};
template&lt; typename T2 &gt;
using TypedefName = SomeType&lt;char*, T2, 5&gt;;
</pre></div>
<p>
SWIG supports both type aliasing and alias templates.
However, in order to use an alias template, two <tt>%template</tt> directives must be used:
</p>
<div class="code"><pre>
%template(SomeTypeBool) SomeType&lt;char*, bool, 5&gt;;
%template() TypedefName&lt;bool&gt;;
</pre></div>
<p>Firstly, the actual template is instantiated with a name to be used by the target language, as per any template being wrapped.
Secondly, the empty template instantiation, <tt>%template()</tt>, is required for the alias template.
This second requirement is necessary to add the appropriate instantiated template type into the type system as SWIG does not automatically instantiate templates.
See the <a href="SWIGPlus.html#SWIGPlus_nn30">Templates</a> section for more general information on wrapping templates.
<H3><a name="CPlusPlus11_unrestricted_unions">7.2.17 Unrestricted unions</a></H3> <H3><a name="CPlusPlus11_unrestricted_unions">7.2.17 Unrestricted unions</a></H3>
@ -999,7 +994,8 @@ Variadic template support requires further work to provide substantial tuple wra
<p> <p>
The new hash tables in the STL are <tt>unordered_set</tt>, <tt>unordered_multiset</tt>, <tt>unordered_map</tt>, <tt>unordered_multimap</tt>. The new hash tables in the STL are <tt>unordered_set</tt>, <tt>unordered_multiset</tt>, <tt>unordered_map</tt>, <tt>unordered_multimap</tt>.
These are not available in SWIG, but in principle should be easily implemented by adapting the current STL containers. These are not available in all target languages.
Any missing support can in principle be easily implemented by adapting the current STL containers.
</p> </p>
<H3><a name="CPlusPlus11_regular_expressions">7.3.4 Regular expressions</a></H3> <H3><a name="CPlusPlus11_regular_expressions">7.3.4 Regular expressions</a></H3>
@ -1034,7 +1030,7 @@ Users would need to write their own typemaps if wrapper references are being use
</p> </p>
<H3><a name="CPlusPlus11_polymorphous_wrappers_for_function_objects">7.3.8 Polymorphous wrappers for function objects</a></H3> <H3><a name="CPlusPlus11_polymorphous_wrappers_for_function_objects">7.3.8 Polymorphic wrappers for function objects</a></H3>
<p> <p>

View file

@ -544,12 +544,16 @@ unless the imclassname attribute is specified in the <a href="CSharp.html#CSharp
<p> <p>
The directory <tt>Examples/csharp</tt> has a number of simple examples. The directory <tt>Examples/csharp</tt> has a number of simple examples.
Visual Studio .NET 2003 solution and project files are available for compiling with the Microsoft .NET C# compiler on Windows. Visual Studio .NET 2003 solution and project files are available for compiling with the Microsoft .NET C#
If your SWIG installation went well on a Unix environment and your C# compiler was detected, you should be able to type <tt>make</tt> in each example directory, compiler on Windows. This also works with newer versions of Visual Studio if you allow
then <tt>ilrun runme.exe</tt> (Portable.NET C# compiler) or <tt>mono runme.exe</tt> (Mono C# compiler) to run the examples. it to convert the solution to the latest version.
If your SWIG installation went well on a Unix environment and your C# compiler was detected, you should be able to type <tt>make</tt> in each example directory.
After SWIG has run and both the C# and C/C++ compilers have finished building,
the examples will be run, by either running <tt>runme.exe</tt> or by running
<tt>mono runme.exe</tt> (Mono C# compiler).
Windows users can also get the examples working using a Windows users can also get the examples working using a
<a href="http://www.cygwin.com">Cygwin</a> or <a href="http://www.mingw.org">MinGW</a> environment for automatic configuration of the example makefiles. <a href="http://www.cygwin.com">Cygwin</a> or <a href="http://www.mingw.org">MinGW</a> environment for automatic configuration of the example makefiles.
Any one of the three C# compilers (Portable.NET, Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path. Any one of the C# compilers (Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path.
<H2><a name="CSharp_void_pointers">20.3 Void pointers</a></H2> <H2><a name="CSharp_void_pointers">20.3 Void pointers</a></H2>
@ -1166,7 +1170,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_negativesonly(int jarg1) {
SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what()); SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what());
return ; return ;
} }
} }
</pre> </pre>
</div> </div>
@ -1233,7 +1236,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_evensonly(int jarg1) {
return ; return ;
} }
} }
} }
</pre> </pre>
</div> </div>
@ -1592,8 +1594,8 @@ public class Base : global::System.IDisposable {
BaseBoolMethod(new Base(b, false), flag); BaseBoolMethod(new Base(b, false), flag);
} }
internal delegate uint SwigDelegateBase_0(uint x); public delegate uint SwigDelegateBase_0(uint x);
internal delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag); public delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
private SwigDelegateBase_0 swigDelegate0; private SwigDelegateBase_0 swigDelegate0;
private SwigDelegateBase_1 swigDelegate1; private SwigDelegateBase_1 swigDelegate1;
@ -1693,6 +1695,31 @@ void SwigDirector_Base::BaseBoolMethod(Base const &amp;b, bool flag) {
</pre> </pre>
</div> </div>
<p>
The delegates from the above example are <tt>public</tt> by default:
</p>
<div class="code">
<pre>
public delegate uint SwigDelegateBase_0(uint x);
public delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
</pre>
</div>
<p>
These can be changed if desired via the <tt>csdirectordelegatemodifiers</tt>
<a href="Customization.html#Customization_features">%feature directive</a>.
For example, using <tt>%feature("csdirectordelegatemodifiers") "internal"</tt>
before SWIG parses the Base class will change all the delegates to <tt>internal</tt>:
</p>
<div class="code">
<pre>
internal delegate uint SwigDelegateBase_0(uint x);
internal delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
</pre>
</div>
<H3><a name="CSharp_director_caveats">20.6.3 Director caveats</a></H3> <H3><a name="CSharp_director_caveats">20.6.3 Director caveats</a></H3>

View file

@ -295,9 +295,9 @@
<p> <p>
The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as: The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:
"Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a "Tiny CLOS is a Scheme implementation of a 'kernelized' CLOS, with a
metaobject protocol. The implementation is even simpler than metaobject protocol. The implementation is even simpler than
the simple CLOS found in `The Art of the Metaobject Protocol,' the simple CLOS found in 'The Art of the Metaobject Protocol',
weighing in at around 850 lines of code, including (some) weighing in at around 850 lines of code, including (some)
comments and documentation." comments and documentation."
</p> </p>

View file

@ -287,7 +287,7 @@
<li><a href="CPlusPlus11.html#CPlusPlus11_strongly_typed_enumerations">Strongly typed enumerations</a> <li><a href="CPlusPlus11.html#CPlusPlus11_strongly_typed_enumerations">Strongly typed enumerations</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_double_angle_brackets">Double angle brackets</a> <li><a href="CPlusPlus11.html#CPlusPlus11_double_angle_brackets">Double angle brackets</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_explicit_conversion_operators">Explicit conversion operators</a> <li><a href="CPlusPlus11.html#CPlusPlus11_explicit_conversion_operators">Explicit conversion operators</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_alias_templates">Alias templates</a> <li><a href="CPlusPlus11.html#CPlusPlus11_alias_templates">Type alias and alias templates</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_unrestricted_unions">Unrestricted unions</a> <li><a href="CPlusPlus11.html#CPlusPlus11_unrestricted_unions">Unrestricted unions</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_variadic_templates">Variadic templates</a> <li><a href="CPlusPlus11.html#CPlusPlus11_variadic_templates">Variadic templates</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_new_string_literals">New string literals</a> <li><a href="CPlusPlus11.html#CPlusPlus11_new_string_literals">New string literals</a>
@ -310,7 +310,7 @@
<li><a href="CPlusPlus11.html#CPlusPlus11_general_purpose_smart_pointers">General-purpose smart pointers</a> <li><a href="CPlusPlus11.html#CPlusPlus11_general_purpose_smart_pointers">General-purpose smart pointers</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_extensible_random_number_facility">Extensible random number facility</a> <li><a href="CPlusPlus11.html#CPlusPlus11_extensible_random_number_facility">Extensible random number facility</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_wrapper_reference">Wrapper reference</a> <li><a href="CPlusPlus11.html#CPlusPlus11_wrapper_reference">Wrapper reference</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphous wrappers for function objects</a> <li><a href="CPlusPlus11.html#CPlusPlus11_polymorphous_wrappers_for_function_objects">Polymorphic wrappers for function objects</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_type_traits_for_metaprogramming">Type traits for metaprogramming</a> <li><a href="CPlusPlus11.html#CPlusPlus11_type_traits_for_metaprogramming">Type traits for metaprogramming</a>
<li><a href="CPlusPlus11.html#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">Uniform method for computing return type of function objects</a> <li><a href="CPlusPlus11.html#CPlusPlus11_uniform_method_for_computing_return_type_of_function_objects">Uniform method for computing return type of function objects</a>
</ul> </ul>
@ -457,6 +457,7 @@
<li><a href="Typemaps.html#Typemaps_nn32">"argout" typemap</a> <li><a href="Typemaps.html#Typemaps_nn32">"argout" typemap</a>
<li><a href="Typemaps.html#Typemaps_nn33">"freearg" typemap</a> <li><a href="Typemaps.html#Typemaps_nn33">"freearg" typemap</a>
<li><a href="Typemaps.html#Typemaps_nn34">"newfree" typemap</a> <li><a href="Typemaps.html#Typemaps_nn34">"newfree" typemap</a>
<li><a href="Typemaps.html#Typemaps_ret">"ret" typemap</a>
<li><a href="Typemaps.html#Typemaps_nn35">"memberin" typemap</a> <li><a href="Typemaps.html#Typemaps_nn35">"memberin" typemap</a>
<li><a href="Typemaps.html#Typemaps_nn36">"varin" typemap</a> <li><a href="Typemaps.html#Typemaps_nn36">"varin" typemap</a>
<li><a href="Typemaps.html#Typemaps_nn37">"varout" typemap</a> <li><a href="Typemaps.html#Typemaps_nn37">"varout" typemap</a>
@ -907,13 +908,14 @@
<li><a href="Guile.html#Guile_nn14">Smobs</a> <li><a href="Guile.html#Guile_nn14">Smobs</a>
<li><a href="Guile.html#Guile_nn15">Garbage Collection</a> <li><a href="Guile.html#Guile_nn15">Garbage Collection</a>
</ul> </ul>
<li><a href="Guile.html#Guile_nn16">Exception Handling</a> <li><a href="Guile.html#Guile_nn16">Native Guile pointers</a>
<li><a href="Guile.html#Guile_nn17">Procedure documentation</a> <li><a href="Guile.html#Guile_nn17">Exception Handling</a>
<li><a href="Guile.html#Guile_nn18">Procedures with setters</a> <li><a href="Guile.html#Guile_nn18">Procedure documentation</a>
<li><a href="Guile.html#Guile_nn19">GOOPS Proxy Classes</a> <li><a href="Guile.html#Guile_nn19">Procedures with setters</a>
<li><a href="Guile.html#Guile_nn20">GOOPS Proxy Classes</a>
<ul> <ul>
<li><a href="Guile.html#Guile_nn20">Naming Issues</a> <li><a href="Guile.html#Guile_nn21">Naming Issues</a>
<li><a href="Guile.html#Guile_nn21">Linking</a> <li><a href="Guile.html#Guile_nn22">Linking</a>
</ul> </ul>
</ul> </ul>
</div> </div>
@ -1014,6 +1016,7 @@
<ul> <ul>
<li><a href="Java.html#Java_helper_functions">C/C++ helper functions</a> <li><a href="Java.html#Java_helper_functions">C/C++ helper functions</a>
<li><a href="Java.html#Java_class_extension">Class extension with %extend</a> <li><a href="Java.html#Java_class_extension">Class extension with %extend</a>
<li><a href="Java.html#Java_proxycode">Class extension with %proxycode</a>
<li><a href="Java.html#Java_exception_handling">Exception handling with %exception and %javaexception</a> <li><a href="Java.html#Java_exception_handling">Exception handling with %exception and %javaexception</a>
<li><a href="Java.html#Java_method_access">Method access with %javamethodmodifiers</a> <li><a href="Java.html#Java_method_access">Method access with %javamethodmodifiers</a>
</ul> </ul>
@ -1529,7 +1532,7 @@
<li><a href="Python.html#Python_builtin_types">Built-in Types</a> <li><a href="Python.html#Python_builtin_types">Built-in Types</a>
<ul> <ul>
<li><a href="Python.html#Python_builtin_limitations">Limitations</a> <li><a href="Python.html#Python_builtin_limitations">Limitations</a>
<li><a href="Python.html#Python_builtin_overloads">Operator overloads -- use them!</a> <li><a href="Python.html#Python_builtin_overloads">Operator overloads and slots -- use them!</a>
</ul> </ul>
<li><a href="Python.html#Python_nn30">Memory management</a> <li><a href="Python.html#Python_nn30">Memory management</a>
<li><a href="Python.html#Python_nn31">Python 2.2 and classic classes</a> <li><a href="Python.html#Python_nn31">Python 2.2 and classic classes</a>
@ -1595,6 +1598,13 @@
<li><a href="Python.html#Python_absimport">Enforcing absolute import semantics</a> <li><a href="Python.html#Python_absimport">Enforcing absolute import semantics</a>
<li><a href="Python.html#Python_importfrominit">Importing from __init__.py</a> <li><a href="Python.html#Python_importfrominit">Importing from __init__.py</a>
<li><a href="Python.html#Python_implicit_namespace_packages">Implicit Namespace Packages</a> <li><a href="Python.html#Python_implicit_namespace_packages">Implicit Namespace Packages</a>
<li><a href="Python.html#Python_package_search">Searching for the wrapper module</a>
<ul>
<li><a href="Python.html#Python_package_search_both_package_modules">Both modules in the same package</a>
<li><a href="Python.html#Python_package_search_wrapper_split">Split modules</a>
<li><a href="Python.html#Python_package_search_both_global_modules">Both modules are global</a>
<li><a href="Python.html#Python_package_search_static">Statically linked C modules</a>
</ul>
</ul> </ul>
<li><a href="Python.html#Python_python3support">Python 3 Support</a> <li><a href="Python.html#Python_python3support">Python 3 Support</a>
<ul> <ul>
@ -1604,6 +1614,11 @@
<li><a href="Python.html#Python_nn77">Byte string output conversion</a> <li><a href="Python.html#Python_nn77">Byte string output conversion</a>
<li><a href="Python.html#Python_2_unicode">Python 2 Unicode</a> <li><a href="Python.html#Python_2_unicode">Python 2 Unicode</a>
</ul> </ul>
<li><a href="Python.html#Python_multithreaded">Support for Multithreaded Applications</a>
<ul>
<li><a href="Python.html#Python_thread_UI">UI for Enabling Multithreading Support</a>
<li><a href="Python.html#Python_thread_performance">Multithread Performance</a>
</ul>
</ul> </ul>
</div> </div>
<!-- INDEX --> <!-- INDEX -->

View file

@ -174,6 +174,9 @@
<p><a name="D_class_code_typemaps"></a><tt>dconstructor</tt>, <tt>ddestructor</tt>, <tt>ddispose</tt> and <tt>ddispose_derived</tt> are used to generate the class constructor, destructor and <tt>dispose()</tt> method, respectively. The auxiliary code for handling the pointer to the C++ object is stored in <tt>dbody</tt> and <tt>dbody_derived</tt>. You can override them for specific types.</p> <p><a name="D_class_code_typemaps"></a><tt>dconstructor</tt>, <tt>ddestructor</tt>, <tt>ddispose</tt> and <tt>ddispose_derived</tt> are used to generate the class constructor, destructor and <tt>dispose()</tt> method, respectively. The auxiliary code for handling the pointer to the C++ object is stored in <tt>dbody</tt> and <tt>dbody_derived</tt>. You can override them for specific types.</p>
<p>
Code can also be injected into the D proxy class using <tt>%proxycode</tt>.
</p>
<H3><a name="D_special_variables">22.3.7 Special variable macros</a></H3> <H3><a name="D_special_variables">22.3.7 Special variable macros</a></H3>
@ -229,7 +232,8 @@ void foo(SomeClass arg) {
%newobject bar(); %newobject bar();
SomeClass *bar(); SomeClass *bar();
%}</pre></div> %}
</pre></div>
<p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like this:</p> <p>The code generated for <tt>foo()</tt> and <tt>bar()</tt> looks like this:</p>
<div class="targetlang"><pre> <div class="targetlang"><pre>
SomeClass foo() { SomeClass foo() {

View file

@ -729,7 +729,7 @@ For instance, the following example uses <tt>%rename</tt> in reverse to generate
<div class="code"> <div class="code">
<pre> <pre>
%rename(foo) foo_i(int); %rename(foo) foo_i(int);
%rename(foo) foo_d(double; %rename(foo) foo_d(double);
void foo_i(int); void foo_i(int);
void foo_d(double); void foo_d(double);
@ -2534,10 +2534,10 @@ also return a pointer to the base class (<tt>Language</tt>) so that only the int
</p> </p>
<p> <p>
Save the code for your language module in a file named "<tt>python.cxx</tt>" and. Save the code for your language module in a file named "<tt>python.cxx</tt>" and
place this file in the <tt>Source/Modules</tt> directory of the SWIG distribution. place this file in the <tt>Source/Modules</tt> directory of the SWIG distribution.
To ensure that your module is compiled into SWIG along with the other language modules, To ensure that your module is compiled into SWIG along with the other language modules,
modify the file <tt>Source/Modules/Makefile.am</tt> to include the additional source modify the file <tt>Source/Makefile.am</tt> to include the additional source
files. In addition, modify the file <tt>Source/Modules/swigmain.cxx</tt> files. In addition, modify the file <tt>Source/Modules/swigmain.cxx</tt>
with an additional command line option that activates the module. Read the source---it's straightforward. with an additional command line option that activates the module. Read the source---it's straightforward.
</p> </p>

View file

@ -30,13 +30,14 @@
<li><a href="#Guile_nn14">Smobs</a> <li><a href="#Guile_nn14">Smobs</a>
<li><a href="#Guile_nn15">Garbage Collection</a> <li><a href="#Guile_nn15">Garbage Collection</a>
</ul> </ul>
<li><a href="#Guile_nn16">Exception Handling</a> <li><a href="#Guile_nn16">Native Guile pointers</a>
<li><a href="#Guile_nn17">Procedure documentation</a> <li><a href="#Guile_nn17">Exception Handling</a>
<li><a href="#Guile_nn18">Procedures with setters</a> <li><a href="#Guile_nn18">Procedure documentation</a>
<li><a href="#Guile_nn19">GOOPS Proxy Classes</a> <li><a href="#Guile_nn19">Procedures with setters</a>
<li><a href="#Guile_nn20">GOOPS Proxy Classes</a>
<ul> <ul>
<li><a href="#Guile_nn20">Naming Issues</a> <li><a href="#Guile_nn21">Naming Issues</a>
<li><a href="#Guile_nn21">Linking</a> <li><a href="#Guile_nn22">Linking</a>
</ul> </ul>
</ul> </ul>
</div> </div>
@ -453,7 +454,14 @@ is exactly like described in <a href="Customization.html#Customization_ownership
Object ownership and %newobject</a> in the SWIG manual. All typemaps use an $owner var, and Object ownership and %newobject</a> in the SWIG manual. All typemaps use an $owner var, and
the guile module replaces $owner with 0 or 1 depending on feature:new.</p> the guile module replaces $owner with 0 or 1 depending on feature:new.</p>
<H2><a name="Guile_nn16">24.8 Exception Handling</a></H2> <H2><a name="Guile_nn16">24.8 Native Guile pointers</a></H2>
<p>
In addition to SWIG smob pointers, <a href="https://www.gnu.org/software/guile/manual/html_node/Foreign-Pointers.html">Guile's native pointer type</a> are accepted as arguments to wrapped SWIG functions. This can be useful for passing <a href="https://www.gnu.org/software/guile/manual/html_node/Void-Pointers-and-Byte-Access.html#">pointers to bytevector data</a> to wrapped functions.
</p>
<H2><a name="Guile_nn17">24.9 Exception Handling</a></H2>
<p> <p>
@ -479,7 +487,7 @@ mapping:
The default when not specified here is to use "swig-error". The default when not specified here is to use "swig-error".
See Lib/exception.i for details. See Lib/exception.i for details.
<H2><a name="Guile_nn17">24.9 Procedure documentation</a></H2> <H2><a name="Guile_nn18">24.10 Procedure documentation</a></H2>
<p>If invoked with the command-line option <code>-procdoc <p>If invoked with the command-line option <code>-procdoc
@ -514,7 +522,7 @@ like this:
typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for
details. details.
<H2><a name="Guile_nn18">24.10 Procedures with setters</a></H2> <H2><a name="Guile_nn19">24.11 Procedures with setters</a></H2>
<p>For global variables, SWIG creates a single wrapper procedure <p>For global variables, SWIG creates a single wrapper procedure
@ -542,7 +550,7 @@ struct members, the procedures <code>(<var>struct</var>-<var>member</var>-get
pointer)</code> and <code>(<var>struct-member</var>-set pointer pointer)</code> and <code>(<var>struct-member</var>-set pointer
value)</code> are <em>not</em> generated. value)</code> are <em>not</em> generated.
<H2><a name="Guile_nn19">24.11 GOOPS Proxy Classes</a></H2> <H2><a name="Guile_nn20">24.12 GOOPS Proxy Classes</a></H2>
<p>SWIG can also generate classes and generic functions for use with <p>SWIG can also generate classes and generic functions for use with
@ -688,7 +696,7 @@ Notice that &lt;Foo&gt; is used before it is defined. The fix is to just put th
<code>%import "foo.h"</code> before the <code>%inline</code> block. <code>%import "foo.h"</code> before the <code>%inline</code> block.
</p> </p>
<H3><a name="Guile_nn20">24.11.1 Naming Issues</a></H3> <H3><a name="Guile_nn21">24.12.1 Naming Issues</a></H3>
<p>As you can see in the example above, there are potential naming conflicts. The default exported <p>As you can see in the example above, there are potential naming conflicts. The default exported
@ -725,7 +733,7 @@ guile-modules. For example,</p>
(use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:))) (use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:)))
</pre></div> </pre></div>
<H3><a name="Guile_nn21">24.11.2 Linking</a></H3> <H3><a name="Guile_nn22">24.12.2 Linking</a></H3>
<p>The guile-modules generated above all need to be linked together. GOOPS support requires <p>The guile-modules generated above all need to be linked together. GOOPS support requires

View file

@ -100,6 +100,7 @@
<ul> <ul>
<li><a href="#Java_helper_functions">C/C++ helper functions</a> <li><a href="#Java_helper_functions">C/C++ helper functions</a>
<li><a href="#Java_class_extension">Class extension with %extend</a> <li><a href="#Java_class_extension">Class extension with %extend</a>
<li><a href="#Java_proxycode">Class extension with %proxycode</a>
<li><a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a> <li><a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
<li><a href="#Java_method_access">Method access with %javamethodmodifiers</a> <li><a href="#Java_method_access">Method access with %javamethodmodifiers</a>
</ul> </ul>
@ -281,7 +282,7 @@ compiling and using the generated files.
<p> <p>
The following table list the additional commandline options available for the Java module. They can also be seen by using: The following table lists the additional commandline options available for the Java module. They can also be seen by using:
</p> </p>
<div class="code"><pre> <div class="code"><pre>
@ -349,7 +350,7 @@ However, SWIG tries to guess the right options when it is installed. Therefore,
you may want to start with one of the examples in the <tt>Examples/java</tt> you may want to start with one of the examples in the <tt>Examples/java</tt>
directory. If that doesn't work, you will need to read the man-pages for directory. If that doesn't work, you will need to read the man-pages for
your compiler and linker to get the right set of options. You might also your compiler and linker to get the right set of options. You might also
check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> for check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> for
additional information. additional information.
</p> </p>
@ -481,7 +482,7 @@ One last piece of advice is to beware of the common faux pas of having more than
In summary, ensure that you are using the correct C/C++ compiler and linker combination and options for successful native library loading. In summary, ensure that you are using the correct C/C++ compiler and linker combination and options for successful native library loading.
If you are using the examples that ship with SWIG, then the Examples/Makefile must have these set up correctly for your system. If you are using the examples that ship with SWIG, then the Examples/Makefile must have these set up correctly for your system.
The SWIG installation package makes a best attempt at getting these correct but does not get it right 100% of the time. The SWIG installation package makes a best attempt at getting these correct but does not get it right 100% of the time.
The <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> also has some settings for commonly used compiler and operating system combinations. The <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> also has some settings for commonly used compiler and operating system combinations.
The following section also contains some C++ specific linking problems and solutions. The following section also contains some C++ specific linking problems and solutions.
</p> </p>
@ -3359,20 +3360,20 @@ There is more than one macro in order to provide a choice for choosing the Java
</tr> </tr>
<tr> <tr>
<td><tt>%interface(CTYPE)</tt></td> <td><tt>%interface(CTYPE)</tt></td>
<td>Proxy class name is unchanged, interface name has <tt>SwigInterface</tt> added as a suffix for C++ class <tt>CTYPE</tt>.</td> <td>For C++ class <tt>CTYPE</tt>, proxy class name is unchanged without any suffix added, interface name has <tt>SwigInterface</tt> added as a suffix.</td>
</tr> </tr>
<tr> <tr>
<td><tt>%interface_impl(CTYPE)</tt></td> <td><tt>%interface_impl(CTYPE)</tt></td>
<td>Proxy class name has <tt>SwigImpl</tt> as a suffix, interface name has <tt>SwigInterface</tt> added as a suffix for C++ class <tt>CTYPE</tt>.</td> <td>For C++ class <tt>CTYPE</tt>, proxy class name has <tt>SwigImpl</tt> added as a suffix, interface name has no added suffix.</td>
</tr> </tr>
<tr> <tr>
<td><tt>%interface_custom("PROXY", "INTERFACE", CTYPE)</tt></td> <td><tt>%interface_custom("PROXY", "INTERFACE", CTYPE)</tt></td>
<td>Proxy class name is given by the string <tt>PROXY</tt>, interface name is given by the string <tt>INTERFACE</tt> for C++ class <tt>CTYPE</tt>. The <tt>PROXY</tt> and <tt>INTERFACE</tt> names can use the <a href="SWIG.html#SWIG_advanced_renaming">string formatting functions</a> used in <tt>%rename</tt>.</td> <td>For C++ class <tt>CTYPE</tt>, proxy class name is given by the string <tt>PROXY</tt>, interface name is given by the string <tt>INTERFACE</tt>. The <tt>PROXY</tt> and <tt>INTERFACE</tt> names can use the <a href="SWIG.html#SWIG_advanced_renaming">string formatting functions</a> used in <tt>%rename</tt>.</td>
</tr> </tr>
</table> </table>
<p> <p>
The table below has a few examples showing the resulting proxy and interface names. The table below has a few examples showing the resulting proxy and interface names for a C++ class called <tt>Base</tt>.
</p> </p>
<table BORDER summary="Java interface macro examples"> <table BORDER summary="Java interface macro examples">
@ -3922,12 +3923,24 @@ is used in the feature code. Consider the following, which also happens to be th
if ($error) { if ($error) {
jenv-&gt;ExceptionClear(); jenv-&gt;ExceptionClear();
$directorthrowshandlers $directorthrowshandlers
throw Swig::DirectorException(jenv, $error); Swig::DirectorException::raise(jenv, $error);
} }
%} %}
</pre> </pre>
</div> </div>
<p>
where <tt>Swig::DirectorException::raise</tt> is a helper method in the DirectorException class to throw a C++ exception (implemented in director.swg):
</p>
<div class="code">
<pre>
static void raise(JNIEnv *jenv, jthrowable throwable) {
throw DirectorException(jenv, throwable);
}
</pre>
</div>
<p>The code generated using the <code>director:except</code> feature <p>The code generated using the <code>director:except</code> feature
replaces the <code>$directorthrowshandlers</code> special variable with the code in replaces the <code>$directorthrowshandlers</code> special variable with the code in
the "directorthrows" typemaps, for each and every exception defined for the method. the "directorthrows" typemaps, for each and every exception defined for the method.
@ -3962,7 +3975,7 @@ if (swigerror) {
throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message()); throw std::out_of_range(Swig::JavaExceptionMessage(jenv, swigerror).message());
} }
throw Swig::DirectorException(jenv, swigerror); Swig::DirectorException::raise(jenv, swigerror);
} }
</pre> </pre>
</div> </div>
@ -4363,7 +4376,144 @@ Vector(2,3,4)
in any way---the extensions only show up in the Java interface. in any way---the extensions only show up in the Java interface.
</p> </p>
<H3><a name="Java_exception_handling">25.7.3 Exception handling with %exception and %javaexception</a></H3> <H3><a name="Java_proxycode">25.7.3 Class extension with %proxycode</a></H3>
<p>
The previous section described how to extend a wrapped class with C or C++ code.
This section describes how to extend a wrapped class with Java code instead of C/C++ code.
The <tt>%proxycode</tt> directive is used and is just a macro for <tt>%insert("proxycode")</tt>.
The <a href="SWIG.html#SWIG_nn42">Code insertion block</a> section describes the <tt>%insert</tt> directive.
The section of code for insertion is "proxycode", that is, the Java proxy class.
This directive must hence only be used within the scope of a class, otherwise it is silently ignored.
There are two common ways to get the scope correct.
</p>
<p>
The first is to use <tt>%proxycode</tt> inside a class that SWIG parses, for example a <tt>toString()</tt> method can be added to a C++ class using pure Java code.
A C++ header file can mix C++ and Java code inside the C++ class as follows:
</p>
<div class="code">
<pre>
// flag.h header file
class Flag {
bool flag;
public:
Flag(bool flag) : flag(flag) {}
bool FetchFlag() { return flag; }
#if defined(SWIG)
%proxycode %{
public String toString() {
boolean flag = FetchFlag();
return Boolean.toString(flag);
}
%}
#endif
};
</pre>
</div>
<p>
and wrapped using:
</p>
<div class="code">
<pre>
%{
#include "flag.h"
%}
%include "flag.h"
</pre>
</div>
<p>
The second is to use <tt>%proxycode</tt> within <tt>%extend</tt> as everything within a <tt>%extend</tt> block is effectively within the scope of the class, for example:
</p>
<div class="code">
<pre>
// flag.h header file
class Flag {
bool flag;
public:
Flag(bool flag) : flag(flag) {}
bool FetchFlag() { return flag; }
};
</pre>
</div>
<p>
and wrapped using:
</p>
<div class="code">
<pre>
%{
#include "flag.h"
%}
%include "flag.h"
%extend Flag {
#if defined(SWIG)
%proxycode %{
public String toString() {
boolean flag = FetchFlag();
return Boolean.toString(flag);
}
%}
#endif
}
</pre>
</div>
<p>
There is some very limited support of typemaps within a <tt>%proxycode</tt> block.
A useful trick is to obtain the Java type for a given C/C++ type using the <a href="Typemaps.html#Typemaps_special_macro_typemap">$typemap</a> special macro.
The following C++ template demonstrates this:
</p>
<div class="code">
<pre>
%inline %{
template&lt;typename T&gt; struct Value {
T value;
Value(const T&amp; val) : value(val) {}
};
%}
%extend Value {
%proxycode %{
public String toString() {
// Note template type expansion is supported, so T is expanded to 'unsigned int' in this example
// and $typemap(jstype, unsigned int) in turn is expanded to 'long'
$typemap(jstype, T) val = getValue();
return "$javaclassname value: " + val + " Java type: $typemap(jstype, T) JNI type: $typemap(jni, T)";
}
%}
}
%template(ValueUnsignedInt) Value&lt;unsigned int&gt;;
</pre>
</div>
<p>
The generated Java contains the expanded special variable and macro resulting in Java proxy code:
</p>
<div class="code">
<pre>
public class ValueUnsignedInt {
...
public String toString() {
long val = getValue();
return "ValueUnsignedInt value: " + val + " Java type: long JNI type: jlong";
}
}
</pre>
</div>
<H3><a name="Java_exception_handling">25.7.4 Exception handling with %exception and %javaexception</a></H3>
<p> <p>
@ -4522,7 +4672,7 @@ to raise exceptions. See the <a href="Library.html#Library">SWIG Library</a> ch
The typemap example <a href="#Java_exception_typemap">Handling C++ exception specifications as Java exceptions</a> provides further exception handling capabilities. The typemap example <a href="#Java_exception_typemap">Handling C++ exception specifications as Java exceptions</a> provides further exception handling capabilities.
</p> </p>
<H3><a name="Java_method_access">25.7.4 Method access with %javamethodmodifiers</a></H3> <H3><a name="Java_method_access">25.7.5 Method access with %javamethodmodifiers</a></H3>
<p> <p>
@ -5543,6 +5693,17 @@ The most important of these implement the mapping of C/C++ types to Java types:
In other words the typemap provides the conversion from the native method call return type. </td> In other words the typemap provides the conversion from the native method call return type. </td>
</tr> </tr>
<tr>
<td>jboxtype</td>
<td>Java boxed type.
These are Java code typemaps to provide the Java boxed type, such as, <tt>Integer</tt> for C type <tt>int</tt>.
As autoboxing is only relevant to the Java primitive types, these are only provided for the
C types that map to Java primitive types.
This typemap is usually only used by C++ STL container wrappers that are wrapped by Java generic
types as the boxed type must be used instead of the unboxed/primitive type when declaring a Java generic type.
</td>
</tr>
<tr> <tr>
<td>javadirectorin</td> <td>javadirectorin</td>
<td>Conversion from jtype to jstype for director methods. <td>Conversion from jtype to jstype for director methods.
@ -6070,6 +6231,9 @@ class modifiers for the Java class: default is "public class"
<p><tt>%typemap(javacode)</tt></p> <p><tt>%typemap(javacode)</tt></p>
<div class="indent"> <div class="indent">
Java code is copied verbatim to the Java class: empty default Java code is copied verbatim to the Java class: empty default
As there can only be one "javacode" typemap per class, also consider using the
<a href="Java.html#Java_proxycode">%proxycode</a> directive which can be used multiple times per class
and offers nearly identical functionality.
</div> </div>
<p><tt>%typemap(javadestruct, methodname="delete", methodmodifiers="public synchronized")</tt> <br></p> <p><tt>%typemap(javadestruct, methodname="delete", methodmodifiers="public synchronized")</tt> <br></p>
@ -6350,11 +6514,24 @@ A typemap for C character strings is:
<div class="code"> <div class="code">
<pre> <pre>
%typemap(directorin,descriptor="Ljava/lang/String;") char * %typemap(directorin, descriptor="Ljava/lang/String;", noblock=1) char * {
%{ $input = jenv-&gt;NewStringUTF($1); %} $input = 0;
if ($1) {
$input = JCALL1(NewStringUTF, jenv, (const char *)$1);
if (!$input) return $null;
}
Swig::LocalRefGuard $1_refguard(jenv, $input);
}
</pre> </pre>
</div> </div>
<p>
The <tt>Swig::LocalRefGuard</tt> class should be used in directorin typemaps for newly allocated objects.
It is used to control local reference counts ensuring the count is decremented after the call up into Java has completed.
Its destructor simply calls <tt>jenv-&gt;DeleteLocalRef(obj)</tt> on the <tt>obj</tt>
passed in during construction.
</p>
<p> <p>
User-defined types have the default "descriptor" attribute "<code>L$packagepath/$javaclassname;</code>" where <code>$packagepath</code> User-defined types have the default "descriptor" attribute "<code>L$packagepath/$javaclassname;</code>" where <code>$packagepath</code>
@ -8315,7 +8492,7 @@ public class FooDerived extends Foo {
public static FooDerived downcastFooDerived(Foo foo_object) public static FooDerived downcastFooDerived(Foo foo_object)
{ {
try { try {
return (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object); return foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object);
} }
catch (ClassCastException exc) { catch (ClassCastException exc) {
@ -8366,10 +8543,8 @@ public abstract class UserVisibleFoo extends Foo {
public static UserVisibleFoo downcastUserVisibleFoo(Foo foo_object) public static UserVisibleFoo downcastUserVisibleFoo(Foo foo_object)
{ {
try { try {
return (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object) : null); return foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object) : null;
} } catch (ClassCastException exc) {
catch (ClassCastException exc) {
// Wasn't a FooDerived object, some other subclass of Foo // Wasn't a FooDerived object, some other subclass of Foo
return null; return null;
} }

View file

@ -1385,16 +1385,24 @@ The following table shows which C++ classes are supported and the equivalent SWI
<td><b>SWIG Interface library file</b></td> <td><b>SWIG Interface library file</b></td>
</tr> </tr>
<tr> <td>std::array (C++11)</td> <td>array</td> <td>std_array.i</td> </tr>
<tr> <td>std::auto_ptr</td> <td>memory</td> <td>std_auto_ptr.i</td> </tr> <tr> <td>std::auto_ptr</td> <td>memory</td> <td>std_auto_ptr.i</td> </tr>
<tr> <td>std::complex</td> <td>complex</td> <td>std_complex.i</td> </tr>
<tr> <td>std::deque</td> <td>deque</td> <td>std_deque.i</td> </tr> <tr> <td>std::deque</td> <td>deque</td> <td>std_deque.i</td> </tr>
<tr> <td>std::list</td> <td>list</td> <td>std_list.i</td> </tr> <tr> <td>std::list</td> <td>list</td> <td>std_list.i</td> </tr>
<tr> <td>std::map</td> <td>map</td> <td>std_map.i</td> </tr> <tr> <td>std::map</td> <td>map</td> <td>std_map.i</td> </tr>
<tr> <td>std::multimap (C++11)</td> <td>multimap</td> <td>std_multimap.i</td> </tr>
<tr> <td>std::multiset (C++11)</td> <td>multiset</td> <td>std_multiset.i</td> </tr>
<tr> <td>std::pair</td> <td>utility</td> <td>std_pair.i</td> </tr> <tr> <td>std::pair</td> <td>utility</td> <td>std_pair.i</td> </tr>
<tr> <td>std::set</td> <td>set</td> <td>std_set.i</td> </tr> <tr> <td>std::set</td> <td>set</td> <td>std_set.i</td> </tr>
<tr> <td>std::string</td> <td>string</td> <td>std_string.i</td> </tr> <tr> <td>std::string</td> <td>string</td> <td>std_string.i</td> </tr>
<tr> <td>std::unordered_map (C++11)</td> <td>unordered_map</td> <td>std_unordered_map.i</td> </tr>
<tr> <td>std::unordered_multimap (C++11)</td> <td>unordered_multimap</td> <td>std_unordered_multimap.i</td> </tr>
<tr> <td>std::unordered_multiset (C++11)</td> <td>unordered_multiset</td> <td>std_unordered_multiset.i</td> </tr>
<tr> <td>std::unordered_set (C++11)</td> <td>unordered_set</td> <td>std_unordered_set.i</td> </tr>
<tr> <td>std::vector</td> <td>vector</td> <td>std_vector.i</td> </tr> <tr> <td>std::vector</td> <td>vector</td> <td>std_vector.i</td> </tr>
<tr> <td>std::array</td> <td>array (C++11)</td> <td>std_array.i</td> </tr> <tr> <td>std::wstring</td> <td>wstring</td> <td>std_wstring.i</td> </tr>
<tr> <td>std::shared_ptr</td> <td>shared_ptr (C++11)</td> <td>std_shared_ptr.i</td> </tr> <tr> <td>std::shared_ptr (C++11)</td> <td>shared_ptr</td> <td>std_shared_ptr.i</td> </tr>
</table> </table>
@ -1903,7 +1911,7 @@ Adding the missing <tt>%shared_ptr</tt> macros will fix this:
<p> <p>
<b>Note:</b> There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature <b>Note:</b> There is somewhat limited support for <tt>%shared_ptr</tt> and the director feature
and the degress of success varies among the different target languages. and the degrees of success varies among the different target languages.
Please help to improve this support by providing patches with improvements. Please help to improve this support by providing patches with improvements.
</p> </p>

View file

@ -122,9 +122,12 @@ swig -cffi -help
<H3><a name="Lisp_nn5">27.2.2 Generating CFFI bindings</a></H3> <H3><a name="Lisp_nn5">27.2.2 Generating CFFI bindings</a></H3>
<p>
As we mentioned earlier the ideal way to use SWIG is to use interface As we mentioned earlier the ideal way to use SWIG is to use interface
files. To illustrate the use of it, let's assume that we have a files. To illustrate the use of it, let's assume that we have a
file named <i>test.h</i> with the following C code: file named <i>test.h</i> with the following C code:
</p>
<div class="code"><pre> <div class="code"><pre>
#define y 5 #define y 5
@ -144,7 +147,6 @@ struct bar * my_struct;
struct foo { struct foo {
int a; int a;
struct foo * b[100]; struct foo * b[100];
}; };
int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p); int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p);
@ -156,7 +158,10 @@ void lispsort_double (int n, double * array);
enum color { RED, BLUE, GREEN}; enum color { RED, BLUE, GREEN};
</pre></div> </pre></div>
<p>
Corresponding to this we will write a simple interface file: Corresponding to this we will write a simple interface file:
</p>
<div class="code"><pre> <div class="code"><pre>
%module test %module test
@ -164,7 +169,9 @@ Corresponding to this we will write a simple interface file:
</pre></div> </pre></div>
<p>
The generated SWIG Code will be: The generated SWIG Code will be:
</p>
<div class="targetlang"><pre> <div class="targetlang"><pre>
;;;SWIG wrapper code starts here ;;;SWIG wrapper code starts here
@ -431,8 +438,10 @@ Also, while parsing the C++ file and generating C wrapper code SWIG
%include "target/header.h" %include "target/header.h"
</pre></div> </pre></div>
<p>
Various features which were available for C headers can also be used Various features which were available for C headers can also be used
here. The target header which we are going to use here is: here. The target header which we are going to use here is:
</p>
<div class="code"><pre> <div class="code"><pre>
namespace OpenDemo { namespace OpenDemo {
class Test class Test
@ -460,16 +469,13 @@ namespace OpenDemo {
static const Test zero; static const Test zero;
}; };
inline Test operator* (float s, const Test&amp; v) {return v*s;} inline Test operator* (float s, const Test&amp; v) {return v*s;}
inline std::ostream&amp; operator&lt;&lt; (std::ostream&amp; o, const Test&amp; v) inline std::ostream&amp; operator&lt;&lt; (std::ostream&amp; o, const Test&amp; v)
{ {
return o &lt;&lt; "(" &lt;&lt; v.x &lt;&lt; ")"; return o &lt;&lt; "(" &lt;&lt; v.x &lt;&lt; ")";
} }
inline Test RandomUnitVectorOnXZPlane (void) inline Test RandomUnitVectorOnXZPlane (void)
{ {
return RandomVectorInUnitRadiusSphere().setYtoZero().normalize(); return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
@ -482,8 +488,10 @@ namespace OpenDemo {
%include "test.cpp" %include "test.cpp"
</pre></div> </pre></div>
<p>
SWIG generates 3 files, the first one is a C wrap which we don't show, SWIG generates 3 files, the first one is a C wrap which we don't show,
the second is the plain CFFI wrapper which is as shown below: the second is the plain CFFI wrapper which is as shown below:
</p>
<div class="targetlang"><pre> <div class="targetlang"><pre>
(cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void (cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void
(self :pointer) (self :pointer)
@ -532,11 +540,13 @@ SWIG generates 3 files, the first one is a C wrap which we don't show,
(cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer) (cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer)
</pre></div> </pre></div>
<p>
The output is pretty good but it fails in disambiguating overloaded The output is pretty good but it fails in disambiguating overloaded
functions such as the constructor, in this case. One way of functions such as the constructor, in this case. One way of
resolving this problem is to make the interface use the rename resolving this problem is to make the interface use the rename
directiv, but hopefully there are better solutions. directiv, but hopefully there are better solutions.
In addition SWIG also generates, a CLOS file In addition SWIG also generates, a CLOS file
</p>
<div class="targetlang"><pre> <div class="targetlang"><pre>

View file

@ -1095,8 +1095,9 @@ Now we extend it with some new code
sprintf(tmp, "Complex(%g, %g)", $self-&gt;re(), $self-&gt;im()); sprintf(tmp, "Complex(%g, %g)", $self-&gt;re(), $self-&gt;im());
return tmp; return tmp;
} }
bool operator==(const Complex&amp; c) bool operator==(const Complex&amp; c) {
{ return ($self-&gt;re()==c.re() &amp;&amp; $self-&gt;im()==c.im());} return ($self-&gt;re()==c.re() &amp;&amp; $self-&gt;im()==c.im());
}
}; };
</pre></div> </pre></div>
<p> <p>
@ -1739,7 +1740,7 @@ ptr=nil -- the iMath* will be GC'ed as normal
<div class="indent"> <div class="indent">
This is the standard function used for converting a Lua userdata to a void*. It takes the value at the given index in the Lua state and converts it to a userdata. It will then provide the necessary type checks, confirming that the pointer is compatible with the type given in 'type'. Then finally setting '*ptr' to the pointer. This is the standard function used for converting a Lua userdata to a void*. It takes the value at the given index in the Lua state and converts it to a userdata. It will then provide the necessary type checks, confirming that the pointer is compatible with the type given in 'type'. Then finally setting '*ptr' to the pointer.
If flags is set to SWIG_POINTER_DISOWN, this is will clear any ownership flag set on the object.<br> If flags is set to SWIG_POINTER_DISOWN, this is will clear any ownership flag set on the object.<br>
The returns a value which can be checked with the macro SWIG_IsOK() This returns a value which can be checked with the macro SWIG_IsOK()
</div> </div>
<p><tt>void SWIG_NewPointerObj(lua_State* L, void* ptr, swig_type_info *type, int own);</tt></p> <p><tt>void SWIG_NewPointerObj(lua_State* L, void* ptr, swig_type_info *type, int own);</tt></p>

View file

@ -1,10 +1,12 @@
# Makefile for generating the SWIG documentation # Makefile for generating the SWIG documentation
# #
# Note that the htmldoc package needs to be installed, but requires patching (using the # Note that the htmldoc package needs to be installed. wkhtmltopdf patched with qt is also required
# margin-left.patch file from this directory) in order to correctly generate the pdf docs. # and can be installed from http://wkhtmltopdf.org/downloads.html.
#
# The .html files are first processed and updated with chapter numbering and anchor names # The .html files are first processed and updated with chapter numbering and anchor names
# are added to the HTML headings using the python scripts. The htmldoc program is then # are added to the HTML headings using the python scripts. The htmldoc program is then
# used to generate the PDF document and single page HTML version of the documentation. # used to generate the single page HTML version of the documentation.
# wkhtmltopdf is used to generate the pdf document from the single page html file.
# HTML TIDY (package also known as tidy) is also required and is used as an aid to HTML # HTML TIDY (package also known as tidy) is also required and is used as an aid to HTML
# validation. # validation.
# #

View file

@ -64,8 +64,15 @@ Also, there are a dozen or so examples in the Examples/octave directory, and hun
<p> <p>
As of SWIG 3.0.7, the Octave module is regularly tested with Octave versions 3.2.4, 3.8.1, and 4.0.0. SWIG is regularly tested against the following versions of Octave: 3.8, 4.0, 4.2.
Use of older Octave versions is not recommended, as these versions are no longer tested with SWIG. </p>
<p>
Every effort is made to maintain backward compatibility with older versions of Octave.
This cannot be guaranteed however, as in recent times new Octave releases have required nontrivial updates to SWIG, which may break backward compatibility for older Octave versions against which SWIG is not regularly tested.
</p>
<p>
The SWIG runtime exports the function <tt>swig_octave_prereq()</tt> for checking the version of Octave. The SWIG runtime exports the function <tt>swig_octave_prereq()</tt> for checking the version of Octave.
</p> </p>

View file

@ -197,7 +197,7 @@ SWIG tries to guess the right options when it is installed. Therefore,
you may want to start with one of the examples in the <tt>SWIG/Examples/perl5</tt> you may want to start with one of the examples in the <tt>SWIG/Examples/perl5</tt>
directory. If that doesn't work, you will need to read the man-pages for directory. If that doesn't work, you will need to read the man-pages for
your compiler and linker to get the right set of options. You might also your compiler and linker to get the right set of options. You might also
check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> for check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> for
additional information. additional information.
</p> </p>
@ -2477,7 +2477,9 @@ is usually accessed as follows:
<div class="code"> <div class="code">
<pre> <pre>
Foo *f; Foo *f;
if (SWIG_ConvertPtr($input, (void **) &amp;f, SWIGTYPE_p_Foo, 0) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;f, SWIGTYPE_p_Foo, 0))) {
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
}
SV *sv = sv_newmortal(); SV *sv = sv_newmortal();
SWIG_MakePtr(sv, f, SWIGTYPE_p_Foo, 0); SWIG_MakePtr(sv, f, SWIGTYPE_p_Foo, 0);
@ -2492,7 +2494,9 @@ variable <tt>$1_descriptor</tt>. For example:
<div class="code"> <div class="code">
<pre> <pre>
%typemap(in) Foo * { %typemap(in) Foo * {
if ((SWIG_ConvertPtr($input,(void **) &amp;$1, $1_descriptor,0)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor, 0))) {
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
}
} }
</pre> </pre>
</div> </div>
@ -2505,7 +2509,9 @@ For example:
<div class="code"> <div class="code">
<pre> <pre>
%typemap(in) Foo * { %typemap(in) Foo * {
if ((SWIG_ConvertPtr($input,(void **) &amp;$1, $descriptor(Foo *), 0)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$1, $descriptor(Foo *), 0))) {
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
}
} }
</pre> </pre>
</div> </div>

View file

@ -49,19 +49,6 @@
<p>
SWIG supports generating wrappers for PHP5. Support for PHP4 was removed
in SWIG 1.3.37. The PHP developers are no longer making new PHP4 releases,
and won't even be patching critical security issues after 2008-08-08, so it
doesn't make much sense for SWIG to continue to support PHP4 now. If you
really need to continue to use PHP4, just stick with SWIG 1.3.36.
</p>
<p>
Currently any PHP5 release should work, but we don't regularly test with
PHP &lt; 5.3.
</p>
<p> <p>
In this chapter, we discuss SWIG's support of PHP. The PHP module In this chapter, we discuss SWIG's support of PHP. The PHP module
was extensively rewritten in release 1.3.26, and support for generating was extensively rewritten in release 1.3.26, and support for generating
@ -70,7 +57,17 @@ of the features available in some of the other languages.
</p> </p>
<p> <p>
In order to use this module, you will need to have a copy of the PHP5 SWIG supports generating wrappers for PHP5 and PHP7. Support for PHP4 was removed
in SWIG 1.3.37.
</p>
<p>
Currently any PHP5 or PHP7 release should work, but we don't regularly test with
PHP &lt; 5.3.
</p>
<p>
In order to use this module, you will need to have a copy of the PHP
include files to compile the SWIG generated files. If you installed include files to compile the SWIG generated files. If you installed
PHP from a binary package, you may need to install a "php-dev" or "php-devel" PHP from a binary package, you may need to install a "php-dev" or "php-devel"
package for these to be installed. You can find out where these files are package for these to be installed. You can find out where these files are
@ -84,12 +81,13 @@ available.
<p> <p>
To build a PHP extension, run swig using the <tt>-php</tt> option as To build a PHP extension, run swig using the <tt>-php5</tt> or
follows: <tt>-php7</tt> option as follows (<tt>-php</tt> is also supported
and currently is an alias for <tt>-php5</tt>):
</p> </p>
<div class="code"><pre> <div class="code"><pre>
swig -php example.i swig -php7 example.i
</pre></div> </pre></div>
<p> <p>
@ -102,13 +100,18 @@ The third file,
<tt>example.php</tt> can be included by PHP scripts. It attempts to <tt>example.php</tt> can be included by PHP scripts. It attempts to
dynamically load the extension and contains extra php code specified dynamically load the extension and contains extra php code specified
in the interface file. If wrapping C++ code with PHP classes, it will in the interface file. If wrapping C++ code with PHP classes, it will
also contain PHP5 class wrappers. also contain PHP class wrappers.
</p> </p>
<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 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>. more detail in <a href="#Php_nn2_6">section 27.2.6</a>. The generated
C++ wrapper will be called example_wrap.cpp (for PHP5) or
example_wrap.cxx (for PHP7 where the default has been changed to align
with SWIG's default for every other language). You can specify a
different extension for the C++ wrapper using <tt>-cppext</tt> -
e.g. if you want example_wrap.cc use <tt>-cppext cc</tt>.
</p> </p>
<p> <p>
@ -273,7 +276,8 @@ if(EASY_TO_MISPEL) {
<p> <p>
The mis-spelled constant will become the string 'EASY_TO_MISPEL', which The mis-spelled constant will become the string 'EASY_TO_MISPEL', which
is treated as true by the if test, when the value of the intended constant is treated as true by the if test, when the value of the intended constant
would be treated as false! would be treated as false! Modern versions of PHP will at least issue
a PHP notice by default when this happens.
</p> </p>
<H3><a name="Php_nn2_2">34.2.2 Global Variables</a></H3> <H3><a name="Php_nn2_2">34.2.2 Global Variables</a></H3>
@ -611,7 +615,7 @@ struct Complex {
</pre></div> </pre></div>
<p> <p>
Would be used in the following way from PHP5: Would be used in the following way from PHP:
</p> </p>
<div class="code"><pre> <div class="code"><pre>
@ -646,7 +650,7 @@ Member variables and methods are accessed using the <tt>-&gt;</tt> operator.
<p> <p>
The <tt>-noproxy</tt> option flattens the object structure and The <tt>-noproxy</tt> option flattens the object structure and
generates collections of named functions (these are the functions generates collections of named functions (these are the functions
which the PHP5 class wrappers call). The above example results which the PHP class wrappers call). The above example results
in the following PHP functions: in the following PHP functions:
</p> </p>
@ -816,6 +820,15 @@ Results in the following in "example.php"
echo "example.php execution\n"; echo "example.php execution\n";
</pre></div> </pre></div>
<p>
The <b>version</b> pragma can be used to add version to generated PHP extension module. The version is inserted in the zend_module_entry block.
</p>
<div class="code"><pre>
%module example
%pragma(php) version="1.5"
</pre></div>
<p> <p>
The <b>include</b> pragma is a short cut to add include statements to The <b>include</b> pragma is a short cut to add include statements to
the example.php file. the example.php file.
@ -1143,12 +1156,20 @@ deleting all the Foo pointers it contains at some point.
<p> <p>
With directors routing method calls to PHP, and proxies routing them With directors routing method calls to PHP, and proxies routing them
to C++, the handling of exceptions is an important concern. By default, the to C++, the handling of exceptions is an important concern. By default, an
directors ignore exceptions that occur during method calls that are exception thrown in PHP code called from C++ causes the PHP interpreter
resolved in PHP. To handle such exceptions correctly, it is necessary to flag that an exception is thrown, then return passes to C++ as if
to temporarily translate them into C++ exceptions. This can be done with the PHP function had returned <code>Null</code>. Assuming the directorout
the %feature("director:except") directive. The following code should typemaps handle this (those SWIG defines by default should) then once
suffice in most cases: control returns to PHP code again, the PHP exception will actually propagate.
</p>
<p>
Sometimes this control flow is problematic, and you want to skip any
handling in the C++ code. To achieve this, it is necessary
to temporarily translate the PHP exception into a C++ exception. This can be
achieved using the %feature("director:except") directive. The following code
should suffice in most cases:
</p> </p>
<div class="code"> <div class="code">

View file

@ -125,7 +125,9 @@ SWIGMZSCHEME Defined when using Mzscheme
SWIGOCAML Defined when using Ocaml SWIGOCAML Defined when using Ocaml
SWIGOCTAVE Defined when using Octave SWIGOCTAVE Defined when using Octave
SWIGPERL Defined when using Perl SWIGPERL Defined when using Perl
SWIGPHP Defined when using PHP SWIGPHP Defined when using PHP5 or PHP7
SWIGPHP5 Defined when using PHP5
SWIGPHP7 Defined when using PHP7
SWIGPIKE Defined when using Pike SWIGPIKE Defined when using Pike
SWIGPYTHON Defined when using Python SWIGPYTHON Defined when using Python
SWIGR Defined when using R SWIGR Defined when using R

View file

@ -51,7 +51,7 @@
<li><a href="#Python_builtin_types">Built-in Types</a> <li><a href="#Python_builtin_types">Built-in Types</a>
<ul> <ul>
<li><a href="#Python_builtin_limitations">Limitations</a> <li><a href="#Python_builtin_limitations">Limitations</a>
<li><a href="#Python_builtin_overloads">Operator overloads -- use them!</a> <li><a href="#Python_builtin_overloads">Operator overloads and slots -- use them!</a>
</ul> </ul>
<li><a href="#Python_nn30">Memory management</a> <li><a href="#Python_nn30">Memory management</a>
<li><a href="#Python_nn31">Python 2.2 and classic classes</a> <li><a href="#Python_nn31">Python 2.2 and classic classes</a>
@ -117,6 +117,13 @@
<li><a href="#Python_absimport">Enforcing absolute import semantics</a> <li><a href="#Python_absimport">Enforcing absolute import semantics</a>
<li><a href="#Python_importfrominit">Importing from __init__.py</a> <li><a href="#Python_importfrominit">Importing from __init__.py</a>
<li><a href="#Python_implicit_namespace_packages">Implicit Namespace Packages</a> <li><a href="#Python_implicit_namespace_packages">Implicit Namespace Packages</a>
<li><a href="#Python_package_search">Searching for the wrapper module</a>
<ul>
<li><a href="#Python_package_search_both_package_modules">Both modules in the same package</a>
<li><a href="#Python_package_search_wrapper_split">Split modules</a>
<li><a href="#Python_package_search_both_global_modules">Both modules are global</a>
<li><a href="#Python_package_search_static">Statically linked C modules</a>
</ul>
</ul> </ul>
<li><a href="#Python_python3support">Python 3 Support</a> <li><a href="#Python_python3support">Python 3 Support</a>
<ul> <ul>
@ -126,6 +133,11 @@
<li><a href="#Python_nn77">Byte string output conversion</a> <li><a href="#Python_nn77">Byte string output conversion</a>
<li><a href="#Python_2_unicode">Python 2 Unicode</a> <li><a href="#Python_2_unicode">Python 2 Unicode</a>
</ul> </ul>
<li><a href="#Python_multithreaded">Support for Multithreaded Applications</a>
<ul>
<li><a href="#Python_thread_UI">UI for Enabling Multithreading Support</a>
<li><a href="#Python_thread_performance">Multithread Performance</a>
</ul>
</ul> </ul>
</div> </div>
<!-- INDEX --> <!-- INDEX -->
@ -393,7 +405,7 @@ However, SWIG tries to guess the right options when it is installed. Therefore,
you may want to start with one of the examples in the <tt>SWIG/Examples/python</tt> you may want to start with one of the examples in the <tt>SWIG/Examples/python</tt>
directory. If that doesn't work, you will need to read the man-pages for directory. If that doesn't work, you will need to read the man-pages for
your compiler and linker to get the right set of options. You might also your compiler and linker to get the right set of options. You might also
check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> for check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> for
additional information. additional information.
</p> </p>
@ -502,7 +514,7 @@ If using static linking, you might want to rely on a different approach
<p> <p>
To use your module, simply use the Python <tt>import</tt> statement. If To use your module, simply use the Python <tt>import</tt> statement. If
all goes well, you will be able to this: all goes well, you will be able to run this:
</p> </p>
<div class="targetlang"><pre> <div class="targetlang"><pre>
@ -907,7 +919,7 @@ only used by the Visual Studio compiler:
Some users have reported success in building extension modules using Cygwin Some users have reported success in building extension modules using Cygwin
and other compilers. However, the problem of building usable DLLs with these and other compilers. However, the problem of building usable DLLs with these
compilers tends to be rather problematic. For the latest information, compilers tends to be rather problematic. For the latest information,
you may want to consult the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl"> you may want to consult the <a href="https://github.com/swig/swig/wiki">
SWIG Wiki</a>. SWIG Wiki</a>.
</p> </p>
@ -1520,7 +1532,6 @@ class Spam {
public: public:
static void foo(); static void foo();
static int bar; static int bar;
}; };
</pre> </pre>
</div> </div>
@ -2435,7 +2446,7 @@ assert(issubclass(B.Derived, A.Base))
</li> </li>
</ul> </ul>
<H4><a name="Python_builtin_overloads">36.4.2.2 Operator overloads -- use them!</a></H4> <H4><a name="Python_builtin_overloads">36.4.2.2 Operator overloads and slots -- use them!</a></H4>
<p>The entire justification for the <tt>-builtin</tt> option is improved <p>The entire justification for the <tt>-builtin</tt> option is improved
@ -2487,52 +2498,110 @@ automatically converted to python slot operators, refer to the file
<tt>python/pyopers.swig</tt> in the SWIG library. <tt>python/pyopers.swig</tt> in the SWIG library.
</p> </p>
<p>There are other very useful python slots that you
may explicitly define using <tt>%feature</tt> directives. For example, <p>
suppose you want to use instances of a wrapped class as keys in a native python Read about all of the available python slots here:
<tt>dict</tt>. That will work as long as you define a hash function for <a href="http://docs.python.org/c-api/typeobj.html">http://docs.python.org/c-api/typeobj.html</a></p>
instances of your class, and use it to define the python <tt>tp_hash</tt>
slot: <p>
There are two ways to define a python slot function: dispatch to a
statically defined function; or dispatch to a method defined on the
operand.
</p>
<p>
To dispatch to a statically defined function, use %feature("python:&lt;slot&gt;"),
where &lt;slot&gt; is the name of a field in a <tt>PyTypeObject, PyNumberMethods,
PyMappingMethods, PySequenceMethods</tt> or <tt>PyBufferProcs</tt>.
You may override (almost) all of these slots.
</p>
<p>
Let's consider an example setting the <tt>tp_hash</tt> slot for the <tt>MyClass</tt> type.
This is akin to providing a <tt>__hash__</tt> method (for non-builtin types) to make a type hashable.
The hashable type can then for example be added to a Python <tt>dict</tt>.
</p> </p>
<div class="code"> <div class="code">
<pre> <pre>
%feature("python:slot", "tp_hash", functype="hashfunc") Cheese::cheeseHashFunc; %feature("python:tp_hash") MyClass "myHashFunc";
class Cheese { class MyClass {
public: public:
Cheese (const char *name); long field1;
long cheeseHashFunc () const; long field2;
...
};
%{
#if PY_VERSION_HEX &gt;= 0x03020000
static Py_hash_t myHashFunc(PyObject *pyobj)
#else
static long myHashFunc(PyObject *pyobj)
#endif
{
MyClass *cobj;
// Convert pyobj to cobj
return (cobj-&gt;field1 * (cobj-&gt;field2 &lt;&lt; 7));
}
%}
</pre>
</div>
<p>
If you examine the generated code, the supplied hash function will now be
the function callback in the tp_hash slot for the builtin type for <tt>MyClass</tt>:
</p>
<div class="code">
<pre>
static PyHeapTypeObject SwigPyBuiltin__MyClass_type = {
...
(hashfunc) myHashFunc, /* tp_hash */
...
</pre>
</div>
<p>
NOTE: It is the responsibility of the programmer (that's you!) to ensure
that a statically defined slot function has the correct signature, the <tt>hashfunc</tt>
typedef in this case.
</p>
<p>
If, instead, you want to dispatch to an instance method, you can
use %feature("python:slot"). For example:
</p>
<div class="code">
<pre>
%feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc;
#if PY_VERSION_HEX &lt; 0x03020000
#define Py_hash_t long
#endif
class MyClass {
public:
Py_hash_t myHashFunc() const;
...
}; };
</pre> </pre>
</div> </div>
<p>This will allow you to write python code like this:</p> <p>
NOTE: Some python slots use a method signature which does not
match the signature of SWIG-wrapped methods. For those slots,
SWIG will automatically generate a "closure" function to re-marshal
the arguments before dispatching to the wrapped method. Setting
the "functype" attribute of the feature enables SWIG to generate
the chosen closure function.
</p>
<div class="targetlang"> <p>
<pre> There is further information on <tt>%feature("python:slot")</tt>
from my MyPackage import Cheese
inventory = {
Cheese("cheddar") : 0,
Cheese("gouda") : 0,
Cheese("camembert") : 0
}
</pre>
</div>
<p>Because you defined the <tt>tp_hash</tt> slot, <tt>Cheese</tt> objects may
be used as hash keys; and when the <tt>cheeseHashFunc</tt> method is invoked
by a python <tt>dict</tt>, it will <b>not</b> go through named method dispatch.
A more detailed discussion about <tt>%feature("python:slot")</tt> can be found
in the file <tt>python/pyopers.swig</tt> in the SWIG library. in the file <tt>python/pyopers.swig</tt> in the SWIG library.
You can read about all of the available python slots here:</p>
<p><a href="http://docs.python.org/c-api/typeobj.html">http://docs.python.org/c-api/typeobj.html</a></p>
<p>You may override (almost) all of the slots defined in the <tt>PyTypeObject,
PyNumberMethods, PyMappingMethods, PySequenceMethods</tt>, and <tt>PyBufferProcs</tt>
structs.
</p> </p>
@ -2897,9 +2966,6 @@ class MyFoo(mymodule.Foo):
<H3><a name="Python_nn34">36.5.2 Director classes</a></H3> <H3><a name="Python_nn34">36.5.2 Director classes</a></H3>
<p> <p>
For each class that has directors enabled, SWIG generates a new class For each class that has directors enabled, SWIG generates a new class
that derives from both the class in question and a special that derives from both the class in question and a special
@ -3652,7 +3718,7 @@ or a NULL pointer perhaps). Here is a simple example of how you might handle th
$action $action
if (!result) { if (!result) {
PyErr_SetString(PyExc_MemoryError, "Not enough memory"); PyErr_SetString(PyExc_MemoryError, "Not enough memory");
return NULL; SWIG_fail;
} }
} }
void *malloc(size_t nbytes); void *malloc(size_t nbytes);
@ -3684,7 +3750,7 @@ that. For example:
$action $action
if (err_occurred()) { if (err_occurred()) {
PyErr_SetString(PyExc_RuntimeError, err_message()); PyErr_SetString(PyExc_RuntimeError, err_message());
return NULL; SWIG_fail;
} }
} }
</pre> </pre>
@ -3705,7 +3771,7 @@ C++ exceptions are also easy to handle. For example, you can write code like th
$action $action
} catch (std::out_of_range &amp;e) { } catch (std::out_of_range &amp;e) {
PyErr_SetString(PyExc_IndexError, const_cast&lt;char*&gt;(e.what())); PyErr_SetString(PyExc_IndexError, const_cast&lt;char*&gt;(e.what()));
return NULL; SWIG_fail;
} }
} }
@ -3719,7 +3785,8 @@ public:
<p> <p>
When raising a Python exception from C, use the <tt>PyErr_SetString()</tt> When raising a Python exception from C, use the <tt>PyErr_SetString()</tt>
function as shown above. The following exception types can be used as the first argument. function as shown above followed by <tt>SWIG_fail</tt>.
The following exception types can be used as the first argument.
</p> </p>
<div class="code"> <div class="code">
@ -3753,6 +3820,13 @@ PyExc_ZeroDivisionError
</pre> </pre>
</div> </div>
<p>
<tt>SWIG_fail</tt> is a C macro which when called within the context of SWIG wrapper function,
will jump to the error handler code. This will call any cleanup code (freeing any temp variables)
and then return from the wrapper function so that the Python interpreter can raise the Python exception.
This macro should always be called after setting a Python error in code snippets, such as typemaps and <tt>%exception</tt>, that are ultimately generated into the wrapper function.
</p>
<p> <p>
The language-independent <tt>exception.i</tt> library file can also be used The language-independent <tt>exception.i</tt> library file can also be used
to raise exceptions. See the <a href="Library.html#Library">SWIG Library</a> chapter. to raise exceptions. See the <a href="Library.html#Library">SWIG Library</a> chapter.
@ -4352,7 +4426,7 @@ You can refine this by supplying an optional parameter name. For example:
$1 = (int) PyLong_AsLong($input); $1 = (int) PyLong_AsLong($input);
if ($1 &lt; 0) { if ($1 &lt; 0) {
PyErr_SetString(PyExc_ValueError, "Expected a nonnegative value."); PyErr_SetString(PyExc_ValueError, "Expected a nonnegative value.");
return NULL; SWIG_fail;
} }
} }
%inline %{ %inline %{
@ -4685,18 +4759,18 @@ object to be used as a <tt>char **</tt> object.
$1 = (char **) malloc((size+1)*sizeof(char *)); $1 = (char **) malloc((size+1)*sizeof(char *));
for (i = 0; i &lt; size; i++) { for (i = 0; i &lt; size; i++) {
PyObject *o = PyList_GetItem($input, i); PyObject *o = PyList_GetItem($input, i);
if (PyString_Check(o)) if (PyString_Check(o)) {
$1[i] = PyString_AsString(PyList_GetItem($input, i)); $1[i] = PyString_AsString(PyList_GetItem($input, i));
else { } else {
PyErr_SetString(PyExc_TypeError,"list must contain strings");
free($1); free($1);
return NULL; PyErr_SetString(PyExc_TypeError, "list must contain strings");
SWIG_fail;
} }
} }
$1[i] = 0; $1[i] = 0;
} else { } else {
PyErr_SetString(PyExc_TypeError, "not a list"); PyErr_SetString(PyExc_TypeError, "not a list");
return NULL; SWIG_fail;
} }
} }
@ -4784,18 +4858,18 @@ previous example:
$2 = (char **) malloc(($1+1)*sizeof(char *)); $2 = (char **) malloc(($1+1)*sizeof(char *));
for (i = 0; i &lt; $1; i++) { for (i = 0; i &lt; $1; i++) {
PyObject *o = PyList_GetItem($input, i); PyObject *o = PyList_GetItem($input, i);
if (PyString_Check(o)) if (PyString_Check(o)) {
$2[i] = PyString_AsString(PyList_GetItem($input, i)); $2[i] = PyString_AsString(PyList_GetItem($input, i));
else { } else {
PyErr_SetString(PyExc_TypeError,"list must contain strings");
free($2); free($2);
return NULL; PyErr_SetString(PyExc_TypeError, "list must contain strings");
SWIG_fail;
} }
} }
$2[i] = 0; $2[i] = 0;
} else { } else {
PyErr_SetString(PyExc_TypeError, "not a list"); PyErr_SetString(PyExc_TypeError, "not a list");
return NULL; SWIG_fail;
} }
} }
@ -4973,12 +5047,12 @@ This too, can be handled used typemaps as follows :
if (PyTuple_Check($input)) { if (PyTuple_Check($input)) {
if (!PyArg_ParseTuple($input, "dddd", temp, temp+1, temp+2, temp+3)) { if (!PyArg_ParseTuple($input, "dddd", temp, temp+1, temp+2, temp+3)) {
PyErr_SetString(PyExc_TypeError, "tuple must have 4 elements"); PyErr_SetString(PyExc_TypeError, "tuple must have 4 elements");
return NULL; SWIG_fail;
} }
$1 = &amp;temp[0]; $1 = &amp;temp[0];
} else { } else {
PyErr_SetString(PyExc_TypeError, "expected a tuple."); PyErr_SetString(PyExc_TypeError, "expected a tuple.");
return NULL; SWIG_fail;
} }
} }
@ -5013,18 +5087,18 @@ arrays of different sizes. To do this, you might write a typemap as follows:
int i; int i;
if (!PySequence_Check($input)) { if (!PySequence_Check($input)) {
PyErr_SetString(PyExc_TypeError, "Expecting a sequence"); PyErr_SetString(PyExc_TypeError, "Expecting a sequence");
return NULL; SWIG_fail;
} }
if (PyObject_Length($input) != $1_dim0) { if (PyObject_Length($input) != $1_dim0) {
PyErr_SetString(PyExc_ValueError, "Expecting a sequence with $1_dim0 elements"); PyErr_SetString(PyExc_ValueError, "Expecting a sequence with $1_dim0 elements");
return NULL; SWIG_fail;
} }
for (i =0; i &lt; $1_dim0; i++) { for (i =0; i &lt; $1_dim0; i++) {
PyObject *o = PySequence_GetItem($input, i); PyObject *o = PySequence_GetItem($input, i);
if (!PyFloat_Check(o)) { if (!PyFloat_Check(o)) {
Py_XDECREF(o); Py_XDECREF(o);
PyErr_SetString(PyExc_ValueError, "Expecting a sequence of floats"); PyErr_SetString(PyExc_ValueError, "Expecting a sequence of floats");
return NULL; SWIG_fail;
} }
temp[i] = PyFloat_AsDouble(o); temp[i] = PyFloat_AsDouble(o);
Py_DECREF(o); Py_DECREF(o);
@ -5081,7 +5155,7 @@ static int convert_darray(PyObject *input, double *ptr, int size) {
%typemap(in) double [ANY](double temp[$1_dim0]) { %typemap(in) double [ANY](double temp[$1_dim0]) {
if (!convert_darray($input, temp, $1_dim0)) { if (!convert_darray($input, temp, $1_dim0)) {
return NULL; SWIG_fail;
} }
$1 = &amp;temp[0]; $1 = &amp;temp[0];
} }
@ -5136,8 +5210,9 @@ is usually accessed as follows:
<div class="code"> <div class="code">
<pre> <pre>
Foo *f; Foo *f;
if (SWIG_ConvertPtr($input, (void **) &amp;f, SWIGTYPE_p_Foo, SWIG_POINTER_EXCEPTION) == -1) if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;f, SWIGTYPE_p_Foo, 0))) {
return NULL; SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
}
PyObject *obj; PyObject *obj;
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0); obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
@ -5152,8 +5227,9 @@ variable <tt>$1_descriptor</tt>. For example:
<div class="code"> <div class="code">
<pre> <pre>
%typemap(in) Foo * { %typemap(in) Foo * {
if ((SWIG_ConvertPtr($input,(void **) &amp;$1, $1_descriptor,SWIG_POINTER_EXCEPTION)) == -1) if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor, 0))) {
return NULL; SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
}
} }
</pre> </pre>
</div> </div>
@ -5166,9 +5242,9 @@ For example:
<div class="code"> <div class="code">
<pre> <pre>
%typemap(in) Foo * { %typemap(in) Foo * {
if ((SWIG_ConvertPtr($input,(void **) &amp;$1, $descriptor(Foo *), if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$1, $descriptor(Foo *), 0))) {
SWIG_POINTER_EXCEPTION)) == -1) SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
return NULL; }
} }
</pre> </pre>
</div> </div>
@ -5521,6 +5597,23 @@ They should be created by other means. Both files (module <tt>*.py</tt> and
directories in order to obtain a desirable package/module hierarchy. directories in order to obtain a desirable package/module hierarchy.
</p> </p>
<p>
Python3 adds another option for packages with
<a href="https://www.python.org/dev/peps/pep-0420/">PEP 0420</a> (implicit
namespace packages). Implicit namespace packages no longer use
__init__.py files. SWIG generated Python modules support implicit
namespace packages. See
<a href="#Python_implicit_namespace_packages">36.11.5 Implicit Namespace
Packages</a> for more information.
</p>
<p>
If you place a SWIG generated module into a Python package then there
are details concerning the way SWIG
<a href="#Python_package_search">searches for the wrapper module</a>
that you may want to familiarize yourself with.
</p>
<p>The way Python defines its modules and packages impacts SWIG users. Some <p>The way Python defines its modules and packages impacts SWIG users. Some
users may need to use special features such as the <tt>package</tt> option in the users may need to use special features such as the <tt>package</tt> option in the
<tt>%module</tt> directive or import related command line options. These are <tt>%module</tt> directive or import related command line options. These are
@ -5680,8 +5773,9 @@ class M2(pkg2.mod3.M3): pass
<p>By default, SWIG would generate <tt>mod2.py</tt> proxy file with <p>By default, SWIG would generate <tt>mod2.py</tt> proxy file with
<tt>import</tt> directive as in point 1. This can be changed with the <tt>import</tt> directive as in point 1. This can be changed with the
<tt>-relativeimport</tt> command line option. The <tt>-relativeimport</tt> instructs <tt>-relativeimport</tt> command line option. The <tt>-relativeimport</tt> instructs
SWIG to organize imports as in point 2 (for Python 2.x) or as in point 4 (for SWIG to organize imports as in point 2 (for Python < 2.7.0) or as in point 4
Python 3, that is when the -py3 command line option is enabled). In short, if you have for Python 2.7.0 and newer. This is a check done at the time the module is
imported. In short, if you have
<tt>mod2.i</tt> and <tt>mod3.i</tt> as above, then without <tt>mod2.i</tt> and <tt>mod3.i</tt> as above, then without
<tt>-relativeimport</tt> SWIG will write</p> <tt>-relativeimport</tt> SWIG will write</p>
@ -5696,21 +5790,16 @@ write</p>
<div class="targetlang"> <div class="targetlang">
<pre> <pre>
import pkg2.mod3 from sys import version_info
</pre> if version_info &gt;= (2, 7, 0):
</div>
<p>if <tt>-py3</tt> is not used, or</p>
<div class="targetlang">
<pre>
from . import pkg2 from . import pkg2
import pkg1.pkg2.mod3 import pkg1.pkg2.mod3
else:
import pkg2.mod3
del version_info
</pre> </pre>
</div> </div>
<p>when <tt>-py3</tt> is used.</p>
<p>You should avoid using relative imports and use absolute ones whenever <p>You should avoid using relative imports and use absolute ones whenever
possible. There are some cases, however, when relative imports may be possible. There are some cases, however, when relative imports may be
necessary. The first example is, when some (legacy) Python code refers entities necessary. The first example is, when some (legacy) Python code refers entities
@ -5943,6 +6032,217 @@ zipimporter requires python-3.5.1 or newer to work with subpackages.
<b>Compatibility Note:</b> Support for implicit namespace packages was added in SWIG-3.0.9. <b>Compatibility Note:</b> Support for implicit namespace packages was added in SWIG-3.0.9.
</p> </p>
<H3><a name="Python_package_search">36.11.6 Searching for the wrapper module</a></H3>
<p>
When SWIG creates wrappers from an interface file, say foo.i, two Python modules are
created. There is a pure Python module module (foo.py) and C/C++ code which is
built and linked into a dynamically (or statically) loaded low-level module _foo
(see the <a href="Python.html#Python_nn3">Preliminaries section</a> for details). So, the interface
file really defines two Python modules. How these two modules are loaded is
covered next.
</p>
<p>
The pure Python module needs to load the C/C++ module in order to link
to the wrapped C/C++ methods. To do this it must make some assumptions
about what package the C/C++ module may be located in. The approach the
pure Python module uses to find the C/C++ module is as follows:
</p>
<ol>
<li><p>The pure Python module, foo.py, tries to load the C/C++ module, _foo, from the same package foo.py is
located in. The package name is determined from the <tt>__name__</tt>
attribute given to foo.py by the Python loader that imported
foo.py. If foo.py is not in a package then _foo is loaded
as a global module.</p>
</li>
<li><p>If the above import of _foo results in an ImportError
being thrown, then foo.py makes a final attempt to load _foo
as a global module.</p>
</li>
</ol>
<p>
The Python code implementing the loading logic described above is quite complex to handle multiple
versions of Python, but it can be replaced with custom code.
This is not recommended unless you understand the full intricacies of importing Python modules.
The custom code can be specified by setting the <tt>moduleimport</tt> option of the <tt>%module</tt> directive with the appropriate import code. For example:
</p>
<div class="code">
<pre>
%module(moduleimport="import _foo") foo
</pre>
</div>
<p>
The special variable <tt>$module</tt> will also be expanded into the low-level C/C++ module name, <tt>_foo</tt> in the case above.
When you have more than just a line or so then you can retain the easy
readability of the <tt>%module</tt> directive by using a macro. For
example:
</p>
<div class="code">
<pre>
%define MODULEIMPORT
"
print 'Loading low-level module $module'
import $module
print 'Module has loaded'
"
%enddef
%module(moduleimport=MODULEIMPORT) foo
</pre>
</div>
<p>
Now let's consider an example using the SWIG default loading logic.
Suppose foo.i is compiled into foo.py and _foo.so. Assuming
/dir is on PYTHONPATH, then the two modules can be installed and used in the
following ways:
</p>
<H4><a name="Python_package_search_both_package_modules">36.11.6.1 Both modules in the same package</a></H4>
<p>Both modules are in one package:</p>
<div class="diagram">
<pre>
/dir/package/foo.py
/dir/package/__init__.py
/dir/package/_foo.so
</pre>
</div>
<p>And imported with</p>
<div class="diagram">
<pre>
from package import foo
</pre>
</div>
<H4><a name="Python_package_search_wrapper_split">36.11.6.2 Split modules</a></H4>
<p>The pure python module is in a package and the C/C++ module is global:</p>
<div class="diagram">
<pre>
/dir/package/foo.py
/dir/package/__init__.py
/dir/_foo.so
</pre>
</div>
<p>And imported with</p>
<div class="diagram">
<pre>
from package import foo
</pre>
</div>
<H4><a name="Python_package_search_both_global_modules">36.11.6.3 Both modules are global</a></H4>
<p>Both modules are global:</p>
<div class="diagram">
<pre>
/dir/foo.py
/dir/_foo.so
</pre>
</div>
<p>And imported with</p>
<div class="diagram">
<pre>
import foo
</pre>
</div>
<p>
If _foo is statically linked into an embedded Python interpreter, then it may or
may not be in a Python package. This depends in the exact way the module was
loaded statically. The above search order will still be used for statically
loaded modules. So, one may place the module either globally or in a package
as desired.
</p>
<H4><a name="Python_package_search_static">36.11.6.4 Statically linked C modules</a></H4>
<p>It is strongly recommended to use dynamically linked modules for the C
portion of your pair of Python modules.
If for some reason you still need
to link the C module of the pair of Python modules generated by SWIG into
your interpreter, then this section provides some details on how this impacts
the pure Python modules ability to locate the other part of the pair.
Please also see the <a href="Python.html#Python_nn8">Static Linking</a> section.
</p>
<p>When Python is extended with C code the Python interpreter needs to be
informed about details of the new C functions that have been linked into
the executable. The code to do this is created by SWIG and is automatically
called in the correct way when the module is dynamically loaded. However
when the code is not dynamically loaded (because it is statically linked)
Then the initialization method for the module created by SWIG is not
called automatically and the Python interpreter has no idea that the
new SWIG C module exists.
</p>
<p>Before Python 3, one could simply call the init method created by SWIG
which would have normally been called when the shared object was dynamically
loaded. The specific name of this method is not given here because statically
linked modules are not encouraged with SWIG
(<a href="Python.html#Python_nn8">Static Linking</a>). However one can find this
init function in the C file generated by SWIG.
</p>
<p>If you are really keen on static linking there are two ways
to initialize the SWIG generated C module with the init method. Which way
you use depends on what version of Python your module is being linked with.
Python 2 and Python 3 treat this init function differently. And the way
they treat it affects how the pure Python module will be able to
locate the C module.
</p>
<p>The details concerning this are covered completly in the documentation
for Python itself. Links to the relavent sections follow:
</p>
<ul>
<li><a href="https://docs.python.org/2/extending/extending.html#methodtable">Extending in python2</a></li>
<li><a href="https://docs.python.org/3.6/extending/extending.html#the-module-s-method-table-and-initialization-function">Extending in python3</a></li>
</ul>
<p>There are two keys things to understand. The first is that in
Python 2 the init() function returns void. In Python 3 the init() function
returns a PyObject * which points to the new module. Secondly, when
you call the init() method manually, you are the Python importer. So, you
determine which package the C module will be located in.
</p>
<p>So, if you are using Python 3 it is important that you follow what is
described in the Python documentation linked above. In particular, you can't
simply call the init() function generated by SWIG and cast the PyObject
pointer it returns over the side. If you do then Python 3 will have no
idea that your C module exists and the pure Python half of your wrapper will
not be able to find it. You need to register your module with the Python
interpreter as described in the Python docs.
</p>
<p>With Python 2 things are somewhat more simple. In this case the init function
returns void. Calling it will register your new C module as a <b>global</b>
module. The pure Python part of the SWIG wrapper will be able to find it
because it tries both the pure Python module it is part of and the global
module. If you wish not to have the statically linked module be a global
module then you will either need to refer to the Python documentation on how
to do this (remember you are now the Python importer) or use dynamic linking.
</p>
<H2><a name="Python_python3support">36.12 Python 3 Support</a></H2> <H2><a name="Python_python3support">36.12 Python 3 Support</a></H2>
@ -6033,7 +6333,7 @@ is backported to 2.6.
<div class="code"><pre> <div class="code"><pre>
%include &lt;pybuffer.i&gt; %include &lt;pybuffer.i&gt;
%pybuffer_mutable_string(char *str); %pybuffer_mutable_string(char *str);
void get_path(char *s); void get_path(char *str);
</pre></div> </pre></div>
<p> <p>
@ -6432,6 +6732,110 @@ the first is allowing unicode conversion and the second is explicitly
prohibiting it. prohibiting it.
</p> </p>
<H2><a name="Python_multithreaded">36.13 Support for Multithreaded Applications</a></H2>
<p>By default, SWIG does not enable support for multithreaded Python applications. More
specifically, the Python wrappers generated by SWIG will not release the
Python's interpreter's Global Interpreter Lock (GIL) when wrapped C/C++ code is
entered. Hence, while any of the wrapped C/C++ code is executing, the Python interpreter
will not be able to run any other threads, even if the wrapped C/C++ code is waiting
in a blocking call for something like network or disk IO.
Fortunately, SWIG does have the ability to enable multithreaded support and automatic
release of the GIL either for all wrapped code in a module or on a more selective basis. The user
interface for this is described in the next section.
</p>
<H3><a name="Python_thread_UI">36.13.1 UI for Enabling Multithreading Support</a></H3>
<p>The user interface is as follows:</p>
<ol>
<li><p>Module thread support can be enabled in two ways:</p>
<ul>
<li>
<p>
The <tt>-threads</tt> swig python option at the command line (or in <tt>setup.py</tt>):
</p>
<div class="shell"><pre>$ swig -python -threads example.i</pre></div>
</li>
<li>
<p>
The <tt>threads</tt> module option in the *.i template file:
</p>
<div class="code"><pre>%feature("nothread") method;</pre></div>
</li>
</ul>
</li>
<li><p>You can disable thread support for a given method:</p>
<div class="code"><pre>%module("threads"=1)</pre></div>
or
<div class="code"><pre>%nothread method;</pre></div>
</li>
<li><p>You can partially disable thread support for a given method:</p>
<ul>
<li><p>To disable the C++/python thread protection:</p>
<div class="code"><pre>%feature("nothreadblock") method;</pre></div>
or
<div class="code"><pre>%nothreadblock method;</pre></div>
</li>
<li>
<p>To disable the python/C++ thread protection</p>
<div class="code"><pre>%feature("nothreadallow") method;</pre></div>
or
<div class="code"><pre>%nothreadallow method;</pre></div>
</li>
</ul>
</li>
</ol>
<H3><a name="Python_thread_performance">36.13.2 Multithread Performance</a></H3>
<p>
For the curious about performance, here are some numbers for the profiletest.i test,
which is used to check the speed of the wrapped code:
</p>
<table summary="Python multithread performance">
<tr>
<th>Thread Mode</th>
<th>Execution Time (sec)</th>
<th>Comment</th>
</tr>
<tr>
<td>Single Threaded</td>
<td>9.6</td>
<td>no "-threads" option given</td>
</tr>
<tr>
<td>Fully Multithreaded</td>
<td>15.5</td>
<td>"-threads" option = 'allow' + 'block'</td>
</tr>
<tr>
<td>No Thread block</td>
<td>12.2</td>
<td>only 'allow'</td>
</tr>
<tr>
<td>No Thread Allow</td>
<td>13.6</td>
<td>only block'</td>
</tr>
</table>
<p>
Fully threaded code decreases the wrapping performance by
around 60%. If that is important to your application, you
can tune each method using the different 'nothread',
'nothreadblock' or 'nothreadallow' features as
needed. Note that for some methods deactivating the
'thread block' or 'thread allow' code is not an option,
so, be careful.
</p>
</body> </body>
</html> </html>

View file

@ -129,7 +129,7 @@ These two files can be loaded in any order
<li>If you do not set the output file name appropriately, you might see errors like <li>If you do not set the output file name appropriately, you might see errors like
<div class="shell"> <div class="shell">
<pre> <pre>
> fact(4) &gt; fact(4)
Error in .Call("R_swig_fact", s_arg1, as.logical(.copy), PACKAGE = "example") : Error in .Call("R_swig_fact", s_arg1, as.logical(.copy), PACKAGE = "example") :
"R_swig_fact" not available for .Call() for package "example" "R_swig_fact" not available for .Call() for package "example"
</pre> </pre>

View file

@ -192,28 +192,13 @@ to compile this file and link it with the rest of your program. </p>
<p> In order to compile the wrapper code, the compiler needs the <tt>ruby.h</tt> <p> In order to compile the wrapper code, the compiler needs the <tt>ruby.h</tt>
header file. This file is usually contained in a directory such as </p> header file and its dependencies, notably <tt>ruby/config.h</tt> which is
found in a different, architecture-dependent, directory. The best way to find
<div class="code shell diagram"> the compiler options needed to compile the code is to ask Ruby itself:</p>
<pre>/usr/lib/ruby/1.8/x86_64-linux-gnu/ruby.h
/usr/include/ruby-2.1.0/ruby.h
</pre>
</div>
<p> The exact location may vary on your machine, but the above
location is typical. If you are not entirely sure where Ruby is
installed, you can run Ruby to find out. For example: </p>
<div class="code shell"> <div class="code shell">
<pre>$ ruby -e 'puts $:.join("\n")' <pre>$ ruby -rrbconfig -e 'puts "-I#{RbConfig::CONFIG[%q{rubyhdrdir}]} -I#{RbConfig::CONFIG[%q{rubyarchhdrdir}]}"'
/usr/local/lib/site_ruby/2.1.0 -I/usr/include/ruby-2.1.0 -I/usr/include/x86_64-linux-gnu/ruby-2.1.0
/usr/local/lib/x86_64-linux-gnu/site_ruby
/usr/local/lib/site_ruby
/usr/lib/ruby/vendor_ruby/2.1.0
/usr/lib/x86_64-linux-gnu/ruby/vendor_ruby/2.1.0
/usr/lib/ruby/vendor_ruby
/usr/lib/ruby/2.1.0
/usr/lib/x86_64-linux-gnu/ruby/2.1.0
</pre> </pre>
</div> </div>
@ -287,7 +272,7 @@ processes). Other compilers may need a different option specified instead of
<p> <p>
If in doubt, consult the If in doubt, consult the
manual pages for your compiler and linker to determine the correct set manual pages for your compiler and linker to determine the correct set
of options. You might also check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> of options. You might also check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a>
for additional information. </p> for additional information. </p>
<H3><a name="Ruby_nn6">38.1.4 Using your module</a></H3> <H3><a name="Ruby_nn6">38.1.4 Using your module</a></H3>

View file

@ -131,7 +131,8 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
-ocaml Generate Ocaml wrappers -ocaml Generate Ocaml wrappers
-octave Generate Octave wrappers -octave Generate Octave wrappers
-perl Generate Perl wrappers -perl Generate Perl wrappers
-php Generate PHP wrappers -php5 Generate PHP5 wrappers
-php7 Generate PHP7 wrappers
-pike Generate Pike wrappers -pike Generate Pike wrappers
-python Generate Python wrappers -python Generate Python wrappers
-r Generate R (aka GNU S) wrappers -r Generate R (aka GNU S) wrappers
@ -142,23 +143,23 @@ can be obtained by typing <tt>swig -help</tt> or <tt>swig
-uffi Generate Common Lisp / UFFI wrappers -uffi Generate Common Lisp / UFFI wrappers
-xml Generate XML wrappers -xml Generate XML wrappers
-c++ Enable C++ parsing -c++ Enable C++ processing
-cppext <em>ext</em> Change file extension of C++ generated files to <em>ext</em> -cppext <em>ext</em> Change file extension of C++ generated files to <em>ext</em>
(default is cxx, except for PHP which uses cpp) (default is cxx, except for PHP5 which uses cpp)
-D<em>symbol</em> Define a preprocessor symbol -D<em>symbol</em> Define a preprocessor symbol
-Fstandard Display error/warning messages in commonly used format
-Fmicrosoft Display error/warning messages in Microsoft format -Fmicrosoft Display error/warning messages in Microsoft format
-Fstandard Display error/warning messages in commonly used format
-help Display all options -help Display all options
-I<em>dir</em> Add a directory to the file include path -I<em>dir</em> Add a directory to the file include path
-l<em>file</em> Include a SWIG library file. -l<em>ifile</em> Include SWIG library file &lt;ifile&gt;
-module <em>name</em> Set the name of the SWIG module -module <em>name</em> Set the name of the SWIG module
-o <em>outfile</em> Set name of C/C++ output file to &lt;outfile&gt; -o <em>outfile</em> Set name of C/C++ output file to &lt;outfile&gt;
-oh <em>headfile</em> Set name of C++ output header file for directors to &lt;headfile&gt; -oh <em>headfile</em> Set name of C++ output header file for directors to &lt;headfile&gt;
-outcurrentdir Set default output dir to current dir instead of input file's path -outcurrentdir Set default output dir to current dir instead of input file's path
-outdir <em>dir</em> Set language specific files output directory -outdir <em>dir</em> Set language specific files output directory
-pcreversion Display PCRE version information -pcreversion Display PCRE version information
-swiglib Show location of SWIG library -swiglib Report location of SWIG library and exit
-version Show SWIG version number -version Display SWIG version number
</pre></div> </pre></div>
@ -749,7 +750,7 @@ form of type-checking however).</p>
<p> <p>
For enumerations, it is critical that the original enum definition be For enumerations, it is critical that the original enum definition be
included somewhere in the interface file (either in a header file or included somewhere in the interface file (either in a header file or
in the <tt>%{,%}</tt> block). SWIG only translates the enumeration in the <tt>%{ %}</tt> block). SWIG only translates the enumeration
into code needed to add the constants to a scripting language. It into code needed to add the constants to a scripting language. It
needs the original enumeration declaration in order to get the correct needs the original enumeration declaration in order to get the correct
enum values as assigned by the C compiler. enum values as assigned by the C compiler.
@ -3139,7 +3140,7 @@ output of SWIG is structured first.</p>
<p> <p>
When SWIG creates its output file, it is broken up into five sections When SWIG creates its output C/C++ file, it is broken up into five sections
corresponding to runtime code, headers, wrapper functions, and module corresponding to runtime code, headers, wrapper functions, and module
initialization code (in that order). initialization code (in that order).
</p> </p>
@ -3175,9 +3176,37 @@ the module upon loading.
<p> <p>
Code is inserted into the appropriate code section by using one The <tt>%insert</tt> directive enables inserting blocks of code into a given section of the generated code.
of the code insertion directives listed below. The order of the sections in It can be used in one of two ways:
the wrapper file is as shown: </p>
<div class="code">
<pre>
%insert("section") "filename"
%insert("section") %{ ... %}
</pre>
</div>
<p>
The first will dump the contents of the file in the given <tt>filename</tt> into the named <tt>section</tt>.
The second inserts the code between the braces into the named <tt>section</tt>.
For example, the following adds code into the runtime section:
</p>
<div class="code">
<pre>
%insert("runtime") %{
... code in runtime section ...
%}
</pre>
</div>
<p>
There are the 5 sections, however, some target languages add in additional sections and some of these result in code being generated into a target language file instead of the C/C++ wrapper file.
These are documented when available in the target language chapters.
Macros named after the code sections are available as additional directives and these macro directives are normally used instead of <tt>%insert</tt>.
For example, <tt>%runtime</tt> is used instead of <tt>%insert("runtime")</tt>.
The valid sections and order of the sections in the generated C/C++ wrapper file is as shown:
</p> </p>
<div class="code"> <div class="code">
@ -3441,7 +3470,7 @@ header files.
<p> <p>
Sometimes, it is necessary to use certain header files in order for Sometimes, it is necessary to use certain header files in order for
the code generated by SWIG to compile properly. Make sure you the code generated by SWIG to compile properly. Make sure you
include certain header files by using a <tt>%{,%}</tt> block like this: include certain header files by using a <tt>%{ %}</tt> block like this:
</p> </p>
<div class="code"><pre> <div class="code"><pre>

View file

@ -2763,8 +2763,27 @@ have to handle it like a normal function. For example:
</li> </li>
<li><p>Certain operators are ignored by default. For instance, <tt>new</tt> and <tt>delete</tt> operators <li><p>Certain operators are ignored by default. For instance, <tt>new</tt> and <tt>delete</tt> operators
are ignored as well as conversion operators. are ignored as well as conversion and index operators. A warning such as the one below is shown:
</p></li> </p>
<div class="shell">
<pre>
example.i:12: Warning 503: Can't wrap 'operator []' unless renamed to a valid identifier.
</pre>
</div>
</li>
<li><p>The index operator, <tt>operator[]</tt>, is particularly difficult to overload due to differences in C++
implementations. Specifically, the get and set operators in other languages typically are separated
into two methods such that additional logic can be packed into the operations; C# uses
<tt>this[type key] { get { ... } set { ... }}</tt>, Python uses
<tt>__getitem__</tt> and <tt>__setitem__</tt>, etc. In C++ if the return
type of <tt>operator[]</tt> is a reference and the method is const, it is often indicative of the <i>setter</i>,
and and the <i>getter</i> is usually a const function return an object by value.
In the absence of any hard and fast rules and the fact that there may be multiple index operators,
it is up to the user to choose the getter and setter to use by using %rename as shown earlier.
</p>
</li>
<li>The semantics of certain C++ operators may not match those in the target language. <li>The semantics of certain C++ operators may not match those in the target language.
</li> </li>
@ -3616,6 +3635,43 @@ This will generate two overloaded wrapper methods, the first will take a single
and the second will take two integer arguments. and the second will take two integer arguments.
</p> </p>
<p>
It is even possible to extend a class via <tt>%extend</tt> with template methods, for example:
</p>
<div class="code">
<pre>
%include &lt;std_string.i&gt;
%inline %{
class ExtendMe {
public:
template &lt;typename T&gt;
T do_stuff_impl(int a, T b, double d) {
return b;
}
};
%}
%extend ExtendMe {
template&lt;typename T&gt;
T do_overloaded_stuff(T b) {
return $self-&gt;do_stuff_impl(0, b, 4.0);
}
}
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff&lt;std::string&gt;;
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff&lt;double&gt;;
</pre>
</div>
<p>
The wrapped <tt>ExtendMe</tt> class will then have two (overloaded) methods called <tt>do_overloaded_stuff</tt>.
</p>
<p>
<b>Compatibility Note</b>: Extending a class with template methods was added in version 3.0.12
</p>
<p> <p>
Needless to say, SWIG's template support provides plenty of opportunities to Needless to say, SWIG's template support provides plenty of opportunities to
break the universe. That said, an important final point is that <b>SWIG does break the universe. That said, an important final point is that <b>SWIG does

View file

@ -304,6 +304,11 @@ The following table lists the Scilab specific command line options in addition t
<td>Generate the gateway XML with the given &lt;gateway_id&gt;</td> <td>Generate the gateway XML with the given &lt;gateway_id&gt;</td>
</tr> </tr>
<tr>
<td><tt>-targetversion</tt></td>
<td>Generate for Scilab target (major) version</td>
</tr>
</table> </table>
<p> <p>
@ -331,13 +336,17 @@ There are a few exceptions, such as constants and enumerations, which can be wra
<p> <p>
In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation should disappear from Scilab 6.0 onwards). In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation disappears from Scilab 6.0 onwards).
<br>Thus long function or variable names may be truncated and this can cause ambiguities. <br>By default, variable, member, and function names longer than 24 charaters are truncated, and a warning is produced for each truncation.
</p> </p>
<p>This happens especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names. <p>This can cause ambiguities, especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names.
In these cases, the <a href="SWIG.html#SWIG_rename_ignore">%rename directive</a> can be used to choose a different Scilab name. In these cases, the <a href="SWIG.html#SWIG_rename_ignore">%rename directive</a> can be used to choose a different Scilab name.
</p> </p>
<p>
Note: truncations can be disabled by specifying the target version 6 of Scilab in the <tt>targetversion</tt> argument (i.e. <tt>-targetversion 6</tt>).
</p>
<H3><a name="Scilab_wrapping_functions">39.3.3 Functions</a></H3> <H3><a name="Scilab_wrapping_functions">39.3.3 Functions</a></H3>
@ -448,8 +457,9 @@ int divide(int n, int d, int q*, int *r) {
*q = n / d; *q = n / d;
*r = n % d; *r = n % d;
return 1; return 1;
} else {
return 0;
} }
else return 0;
} }
%} %}
</pre></div> </pre></div>
@ -1123,7 +1133,7 @@ But we can use either use the <tt>get_perimeter()</tt> function of the parent cl
<p> <p>
As explained in <a href="http://www.swig.org/Doc3.0/SWIGPlus.html#SWIGPlus_overloaded_methods">6.15</a> SWIG provides support for overloaded functions and constructors. As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">6.15</a> SWIG provides support for overloaded functions and constructors.
</p> </p>
<p>As SWIG knows pointer types, the overloading works also with pointer types, here is is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>: <p>As SWIG knows pointer types, the overloading works also with pointer types, here is is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:

View file

@ -8,7 +8,7 @@
<H1><a name="Sections">SWIG-3.0 Documentation</a></H1> <H1><a name="Sections">SWIG-3.0 Documentation</a></H1>
<p> <p>
Last update : SWIG-3.0.10 (in progress) Last update : SWIG-4.0.0 (in progress)
</p> </p>
<H2><a name="Sections_Sections">Sections</a></H2> <H2><a name="Sections_Sections">Sections</a></H2>

View file

@ -151,7 +151,7 @@ SWIG tries to guess the right options when it is installed. Therefore,
you may want to start with one of the examples in the <tt>SWIG/Examples/tcl</tt> you may want to start with one of the examples in the <tt>SWIG/Examples/tcl</tt>
directory. If that doesn't work, you will need to read the man-pages for directory. If that doesn't work, you will need to read the man-pages for
your compiler and linker to get the right set of options. You might also your compiler and linker to get the right set of options. You might also
check the <a href="http://www.dabeaz.com/cgi-bin/wiki.pl">SWIG Wiki</a> for check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> for
additional information. additional information.
</p> </p>
@ -1304,7 +1304,6 @@ class Spam {
public: public:
static void foo(); static void foo();
static int bar; static int bar;
}; };
</pre> </pre>
</div> </div>
@ -3032,7 +3031,6 @@ work)
int len; int len;
$1 = Tcl_GetStringFromObj(interp, &amp;len); $1 = Tcl_GetStringFromObj(interp, &amp;len);
} }
}
</pre> </pre>
</div> </div>
@ -3090,7 +3088,9 @@ is usually accessed as follows:
<div class="indent"> <div class="indent">
<pre> <pre>
Foo *f; Foo *f;
if (SWIG_ConvertPtr($input, (void **) &amp;f, SWIGTYPE_p_Foo, 0) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;f, SWIGTYPE_p_Foo, 0))) {
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
}
Tcl_Obj *; Tcl_Obj *;
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0); obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
@ -3105,7 +3105,9 @@ variable <tt>$1_descriptor</tt>. For example:
<div class="indent"> <div class="indent">
<pre> <pre>
%typemap(in) Foo * { %typemap(in) Foo * {
if ((SWIG_ConvertPtr($input,(void **) &amp;$1, $1_descriptor,0)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor, 0))) {
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
}
} }
</pre> </pre>
</div> </div>
@ -3118,7 +3120,9 @@ For example:
<div class="indent"> <div class="indent">
<pre> <pre>
%typemap(in) Foo * { %typemap(in) Foo * {
if ((SWIG_ConvertPtr($input,(void **) &amp;$1, $descriptor(Foo *), 0)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$1, $descriptor(Foo *), 0))) {
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
}
} }
</pre> </pre>
</div> </div>

View file

@ -63,6 +63,7 @@
<li><a href="#Typemaps_nn32">"argout" typemap</a> <li><a href="#Typemaps_nn32">"argout" typemap</a>
<li><a href="#Typemaps_nn33">"freearg" typemap</a> <li><a href="#Typemaps_nn33">"freearg" typemap</a>
<li><a href="#Typemaps_nn34">"newfree" typemap</a> <li><a href="#Typemaps_nn34">"newfree" typemap</a>
<li><a href="#Typemaps_ret">"ret" typemap</a>
<li><a href="#Typemaps_nn35">"memberin" typemap</a> <li><a href="#Typemaps_nn35">"memberin" typemap</a>
<li><a href="#Typemaps_nn36">"varin" typemap</a> <li><a href="#Typemaps_nn36">"varin" typemap</a>
<li><a href="#Typemaps_nn37">"varout" typemap</a> <li><a href="#Typemaps_nn37">"varout" typemap</a>
@ -375,7 +376,7 @@ example, you could write a typemap like this:
$1 = PyFloat_AsDouble($input); $1 = PyFloat_AsDouble($input);
if ($1 &lt; 0) { if ($1 &lt; 0) {
PyErr_SetString(PyExc_ValueError, "argument must be nonnegative."); PyErr_SetString(PyExc_ValueError, "argument must be nonnegative.");
return NULL; SWIG_fail;
} }
} }
@ -488,7 +489,7 @@ int foo(<b>int x, double y, char *s</b>);
<ul> <ul>
<li>Input argument conversion ("in" typemap).</li> <li>Input argument conversion ("in" typemap).</li>
<li>Input argument type checking ("typecheck" typemap).</li> <li>Input argument type checking for types used in overloaded methods ("typecheck" typemap).</li>
<li>Output argument handling ("argout" typemap).</li> <li>Output argument handling ("argout" typemap).</li>
<li>Input argument value checking ("check" typemap).</li> <li>Input argument value checking ("check" typemap).</li>
<li>Input argument initialization ("arginit" typemap).</li> <li>Input argument initialization ("arginit" typemap).</li>
@ -2585,6 +2586,7 @@ to see whether or not it matches a specific type. For example:
<p> <p>
For typechecking, the $1 variable is always a simple integer that is set to 1 or 0 depending on whether or not For typechecking, the $1 variable is always a simple integer that is set to 1 or 0 depending on whether or not
the input argument is the correct type. the input argument is the correct type.
Set to 1 if the input argument is the correct type otherwise set to 0.
</p> </p>
<p> <p>
@ -2802,7 +2804,46 @@ string *foo();
See <a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for further details. See <a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for further details.
</p> </p>
<H3><a name="Typemaps_nn35">11.5.10 "memberin" typemap</a></H3> <H3><a name="Typemaps_ret">11.5.10 "ret" typemap</a></H3>
<p>
The "ret" typemap is not used very often, but can be useful for anything associated with
the return type, such as resource management, return value error checking, etc.
Usually this can all be done in the "out" typemap, but sometimes it is handy to use the
"out" typemap code untouched and add to the generated code using the code in the "ret" typemap.
One such case is memory clean up. For example, a <tt>stringheap_t</tt> type is defined indicating
that the returned memory must be deleted and a <tt>string_t</tt> type is defined indicating
that the returned memory must not be deleted.
</p>
<div class="code">
<pre>
%typemap(ret) stringheap_t %{
free($1);
%}
typedef char * string_t;
typedef char * stringheap_t;
string_t MakeString1();
stringheap_t MakeString2();
</pre>
</div>
<p>
The "ret" typemap above will only be used for <tt>MakeString2</tt>, but both functions
will use the default "out" typemap for <tt>char *</tt> provided by SWIG.
The code above would ensure the appropriate memory is freed in all target languages as the need
to provide custom "out" typemaps (which involve target language specific code) is not necessary.
</p>
<p>
This approach is an alternative to using the "newfree" typemap and <tt>%newobject</tt> as there
is no need to list all the functions that require the memory cleanup, it is purely done on types.
</p>
<H3><a name="Typemaps_nn35">11.5.11 "memberin" typemap</a></H3>
<p> <p>
@ -2824,7 +2865,7 @@ It is rarely necessary to write "memberin" typemaps---SWIG already provides
a default implementation for arrays, strings, and other objects. a default implementation for arrays, strings, and other objects.
</p> </p>
<H3><a name="Typemaps_nn36">11.5.11 "varin" typemap</a></H3> <H3><a name="Typemaps_nn36">11.5.12 "varin" typemap</a></H3>
<p> <p>
@ -2832,7 +2873,7 @@ The "varin" typemap is used to convert objects in the target language to C for t
purposes of assigning to a C/C++ global variable. This is implementation specific. purposes of assigning to a C/C++ global variable. This is implementation specific.
</p> </p>
<H3><a name="Typemaps_nn37">11.5.12 "varout" typemap</a></H3> <H3><a name="Typemaps_nn37">11.5.13 "varout" typemap</a></H3>
<p> <p>
@ -2840,7 +2881,7 @@ The "varout" typemap is used to convert a C/C++ object to an object in the targe
language when reading a C/C++ global variable. This is implementation specific. language when reading a C/C++ global variable. This is implementation specific.
</p> </p>
<H3><a name="throws_typemap">11.5.13 "throws" typemap</a></H3> <H3><a name="throws_typemap">11.5.14 "throws" typemap</a></H3>
<p> <p>
@ -2875,7 +2916,6 @@ try {
catch(char const *_e) { catch(char const *_e) {
PyErr_SetString(PyExc_RuntimeError, _e); PyErr_SetString(PyExc_RuntimeError, _e);
SWIG_fail; SWIG_fail;
} }
... ...
</pre> </pre>
@ -2924,11 +2964,11 @@ similar to this:
int i; int i;
if (!PySequence_Check($input)) { if (!PySequence_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expected a sequence"); PyErr_SetString(PyExc_ValueError, "Expected a sequence");
return NULL; SWIG_fail;
} }
if (PySequence_Length($input) != 4) { if (PySequence_Length($input) != 4) {
PyErr_SetString(PyExc_ValueError, "Size mismatch. Expected 4 elements"); PyErr_SetString(PyExc_ValueError, "Size mismatch. Expected 4 elements");
return NULL; SWIG_fail;
} }
for (i = 0; i &lt; 4; i++) { for (i = 0; i &lt; 4; i++) {
PyObject *o = PySequence_GetItem($input, i); PyObject *o = PySequence_GetItem($input, i);
@ -2936,7 +2976,7 @@ similar to this:
temp[i] = (float) PyFloat_AsDouble(o); temp[i] = (float) PyFloat_AsDouble(o);
} else { } else {
PyErr_SetString(PyExc_ValueError, "Sequence elements must be numbers"); PyErr_SetString(PyExc_ValueError, "Sequence elements must be numbers");
return NULL; SWIG_fail;
} }
} }
$1 = temp; $1 = temp;
@ -2969,11 +3009,11 @@ If you wanted to generalize the typemap to apply to arrays of all dimensions you
int i; int i;
if (!PySequence_Check($input)) { if (!PySequence_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expected a sequence"); PyErr_SetString(PyExc_ValueError, "Expected a sequence");
return NULL; SWIG_fail;
} }
if (PySequence_Length($input) != $1_dim0) { if (PySequence_Length($input) != $1_dim0) {
PyErr_SetString(PyExc_ValueError, "Size mismatch. Expected $1_dim0 elements"); PyErr_SetString(PyExc_ValueError, "Size mismatch. Expected $1_dim0 elements");
return NULL; SWIG_fail;
} }
for (i = 0; i &lt; $1_dim0; i++) { for (i = 0; i &lt; $1_dim0; i++) {
PyObject *o = PySequence_GetItem($input, i); PyObject *o = PySequence_GetItem($input, i);
@ -2981,7 +3021,7 @@ If you wanted to generalize the typemap to apply to arrays of all dimensions you
temp[i] = (float) PyFloat_AsDouble(o); temp[i] = (float) PyFloat_AsDouble(o);
} else { } else {
PyErr_SetString(PyExc_ValueError, "Sequence elements must be numbers"); PyErr_SetString(PyExc_ValueError, "Sequence elements must be numbers");
return NULL; SWIG_fail;
} }
} }
$1 = temp; $1 = temp;
@ -3013,11 +3053,11 @@ as shown. To work with heap allocated data, the following technique can be use
int i; int i;
if (!PySequence_Check($input)) { if (!PySequence_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expected a sequence"); PyErr_SetString(PyExc_ValueError, "Expected a sequence");
return NULL; SWIG_fail;
} }
if (PySequence_Length($input) != $1_dim0) { if (PySequence_Length($input) != $1_dim0) {
PyErr_SetString(PyExc_ValueError, "Size mismatch. Expected $1_dim0 elements"); PyErr_SetString(PyExc_ValueError, "Size mismatch. Expected $1_dim0 elements");
return NULL; SWIG_fail;
} }
$1 = (float *) malloc($1_dim0*sizeof(float)); $1 = (float *) malloc($1_dim0*sizeof(float));
for (i = 0; i &lt; $1_dim0; i++) { for (i = 0; i &lt; $1_dim0; i++) {
@ -3025,9 +3065,9 @@ as shown. To work with heap allocated data, the following technique can be use
if (PyNumber_Check(o)) { if (PyNumber_Check(o)) {
$1[i] = (float) PyFloat_AsDouble(o); $1[i] = (float) PyFloat_AsDouble(o);
} else { } else {
PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");
free($1); free($1);
return NULL; PyErr_SetString(PyExc_ValueError, "Sequence elements must be numbers");
SWIG_fail;
} }
} }
} }
@ -3189,7 +3229,7 @@ pointers. For example:</p>
%typemap(check) Vector * { %typemap(check) Vector * {
if ($1 == 0) { if ($1 == 0) {
PyErr_SetString(PyExc_TypeError, "NULL Pointer not allowed"); PyErr_SetString(PyExc_TypeError, "NULL Pointer not allowed");
return NULL; SWIG_fail;
} }
} }
@ -3468,7 +3508,7 @@ maps perform the conversion described for the above example:
int i; int i;
if (!PyList_Check($input)) { if (!PyList_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a list"); PyErr_SetString(PyExc_ValueError, "Expecting a list");
return NULL; SWIG_fail;
} }
$1 = PyList_Size($input); $1 = PyList_Size($input);
$2 = (char **) malloc(($1+1)*sizeof(char *)); $2 = (char **) malloc(($1+1)*sizeof(char *));
@ -3477,7 +3517,7 @@ maps perform the conversion described for the above example:
if (!PyString_Check(s)) { if (!PyString_Check(s)) {
free($2); free($2);
PyErr_SetString(PyExc_ValueError, "List items must be strings"); PyErr_SetString(PyExc_ValueError, "List items must be strings");
return NULL; SWIG_fail;
} }
$2[i] = PyString_AsString(s); $2[i] = PyString_AsString(s);
} }
@ -3593,7 +3633,7 @@ might write typemaps like this:
%typemap(in) (void *wbuffer, size_t len) { %typemap(in) (void *wbuffer, size_t len) {
if (!PyString_Check($input)) { if (!PyString_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting a string"); PyErr_SetString(PyExc_ValueError, "Expecting a string");
return NULL; SWIG_fail;
} }
$1 = (void *) PyString_AsString($input); $1 = (void *) PyString_AsString($input);
$2 = PyString_Size($input); $2 = PyString_Size($input);
@ -3603,12 +3643,12 @@ might write typemaps like this:
%typemap(in) (void *rbuffer, size_t len) { %typemap(in) (void *rbuffer, size_t len) {
if (!PyInt_Check($input)) { if (!PyInt_Check($input)) {
PyErr_SetString(PyExc_ValueError, "Expecting an integer"); PyErr_SetString(PyExc_ValueError, "Expecting an integer");
return NULL; SWIG_fail;
} }
$2 = PyInt_AsLong($input); $2 = PyInt_AsLong($input);
if ($2 &lt; 0) { if ($2 &lt; 0) {
PyErr_SetString(PyExc_ValueError, "Positive integer expected"); PyErr_SetString(PyExc_ValueError, "Positive integer expected");
return NULL; SWIG_fail;
} }
$1 = (void *) malloc($2); $1 = (void *) malloc($2);
} }
@ -3864,9 +3904,9 @@ A fragment can use one or more additional fragments, for example:
<div class="code"> <div class="code">
<pre> <pre>
%fragment("&lt;limits.h&gt;", "header") { %fragment("&lt;limits.h&gt;", "header") %{
%#include &lt;limits.h&gt; #include &lt;limits.h&gt;
} %}
%fragment("AsMyClass", "header", fragment="&lt;limits.h&gt;") { %fragment("AsMyClass", "header", fragment="&lt;limits.h&gt;") {
@ -3949,8 +3989,91 @@ Finally, you can force the inclusion of a fragment at any point in the generated
</div> </div>
<p> <p>
which is very useful inside a template class, for example. which, for example, is very useful inside a template class.
Another useful case is when using <tt>%extend</tt> inside a class
where the additional code in the <tt>%extend</tt> block depends on the contents of the fragment.
</p> </p>
<div class="code">
<pre>
%fragment("&lt;limits.h&gt;", "header") %{
#include &lt;limits.h&gt;
%}
struct X {
...
%extend {
%fragment("&lt;limits.h&gt;");
bool check(short val) {
if (val &lt; SHRT_MIN /*defined in &lt;limits.h&gt;*/) {
return true;
} else {
return false;
}
}
}
};
</pre>
</div>
<p>
Forced inclusion of fragments can be used as a replacement for <a href="SWIG.html#SWIG_nn42">code insertion block</a>, ensuring the
code block is only generated once.
Consider the contents of FileA.i below which first uses a code insertion block and then a forced fragment inclusion to generate code:
<p>
<div class="code">
<pre>
// FileA.i
%{
#include &lt;stdio.h&gt;
%}
%fragment("&lt;limits.h&gt;");
</pre>
</div>
<p>
and another file including the above:
</p>
<div class="code">
<pre>
// FileB.i
%include "FileA.i"
</pre>
</div>
<p>
The resulting code in the wrappers for FileB.i is:
</p>
<div class="code">
<pre>
#include &lt;stdio.h&gt;
#include &lt;limits.h&gt;
</pre>
</div>
<p>
A note of caution must be mentioned when using <tt>%fragment</tt> forced inclusion or code insertion blocks with <tt>%import</tt>.
If <tt>%import</tt> is used instead:
<p>
<div class="code">
<pre>
// FileC.i
%import "FileA.i"
</pre>
</div>
<p>
then nothing is generated in the resulting code in the wrappers for FileC.i.
This is because <tt>%import</tt> is for collecting type information and does not result in any code
being generated, see <a href="Preprocessor.html#Preprocessor_nn3">File Imports</a>.
</p>
</ol> </ol>
<p> <p>
@ -4099,14 +4222,17 @@ For example:
<div class="code"> <div class="code">
<pre> <pre>
class Foo { class Foo {
public:
int x; int x;
}; };
class Bar { class Bar {
public:
int y; int y;
}; };
class FooBar : public Foo, public Bar { class FooBar : public Foo, public Bar {
public:
int z; int z;
}; };
</pre> </pre>
@ -4141,12 +4267,15 @@ handling of pointer values (and to make adjustments when needed).
<p> <p>
In the wrapper code generated for each language, pointers are handled through In the wrapper code generated for each language, pointers are handled through
the use of special type descriptors and conversion functions. For example, the use of special type descriptors and conversion functions. For example,
if you look at the wrapper code for Python, you will see code like this: if you look at the wrapper code for Python, you will see code similar to the following
(simplified for brevity):
</p> </p>
<div class="code"> <div class="code">
<pre> <pre>
if ((SWIG_ConvertPtr(obj0,(void **) &amp;arg1, SWIGTYPE_p_Foo,1)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr(obj0, (void **) &amp;arg1, SWIGTYPE_p_Foo, 0))) {
SWIG_exception_fail(SWIG_TypeError, "in method 'GrabVal', expecting type Foo");
}
</pre> </pre>
</div> </div>
@ -4158,8 +4287,10 @@ target language, a list of equivalent typenames (via typedef or
inheritance), and pointer value handling information (if applicable). inheritance), and pointer value handling information (if applicable).
The <tt>SWIG_ConvertPtr()</tt> function is simply a utility function The <tt>SWIG_ConvertPtr()</tt> function is simply a utility function
that takes a pointer object in the target language and a that takes a pointer object in the target language and a
type-descriptor objects and uses this information to generate a C++ type-descriptor object and uses this information to generate a C++ pointer.
pointer. However, the exact name and calling conventions of the conversion The <tt>SWIG_IsOK</tt> macro checks the return value for errors and
<tt>SWIG_exception_fail</tt> can be called to raise an exception in the target language.
However, the exact name and calling conventions of the conversion
function depends on the target language (see language specific chapters for details). function depends on the target language (see language specific chapters for details).
</p> </p>
@ -4265,7 +4396,9 @@ similar to this:
<div class="code"> <div class="code">
<pre> <pre>
%typemap(in) Foo * { %typemap(in) Foo * {
if ((SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor)) == -1) return NULL; if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor, 0))) {
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
}
} }
</pre> </pre>
</div> </div>
@ -4298,10 +4431,10 @@ descriptor name for any C datatype. For example:
<div class="code"> <div class="code">
<pre> <pre>
%typemap(in) Foo * { %typemap(in) Foo * {
if ((SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor)) == -1) { if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;$1, $1_descriptor, 0))) {
Bar *temp; Bar *temp;
if ((SWIG_ConvertPtr($input, (void **) &amp;temp, <b>$descriptor(Bar *)</b>) == -1) { if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &amp;temp, $descriptor(Bar *), 0))) {
return NULL; SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo or Bar");
} }
$1 = (Foo *)temp; $1 = (Foo *)temp;
} }
@ -4549,38 +4682,13 @@ The following excerpt from the Python module illustrates this:
$1 = PyString_Check($input) ? 1 : 0; $1 = PyString_Check($input) ? 1 : 0;
} }
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &amp;, SWIGTYPE [] { %typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, noblock=1) SWIGTYPE * {
void *ptr; void *vptr = 0;
if (SWIG_ConvertPtr($input, (void **) &amp;ptr, $1_descriptor, 0) == -1) { int res = SWIG_ConvertPtr($input, &amp;vptr, $1_descriptor, 0);
$1 = 0; $1 = SWIG_IsOK(res) ? 1 : 0;
PyErr_Clear();
} else {
$1 = 1;
}
} }
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { %typecheck(SWIG_TYPECHECK_POINTER) PyObject * {
void *ptr;
if (SWIG_ConvertPtr($input, (void **) &amp;ptr, $&amp;1_descriptor, 0) == -1) {
$1 = 0;
PyErr_Clear();
} else {
$1 = 1;
}
}
%typecheck(SWIG_TYPECHECK_VOIDPTR) void * {
void *ptr;
if (SWIG_ConvertPtr($input, (void **) &amp;ptr, 0, 0) == -1) {
$1 = 0;
PyErr_Clear();
} else {
$1 = 1;
}
}
%typecheck(SWIG_TYPECHECK_POINTER) PyObject *
{
$1 = ($input != 0); $1 = ($input != 0);
} }
</pre> </pre>

View file

@ -517,7 +517,7 @@ like this:
argc = PyTuple_Size(varargs); argc = PyTuple_Size(varargs);
if (argc &gt; 10) { if (argc &gt; 10) {
PyErr_SetString(PyExc_ValueError, "Too many arguments"); PyErr_SetString(PyExc_ValueError, "Too many arguments");
return NULL; SWIG_fail;
} }
for (i = 0; i &lt; argc; i++) { for (i = 0; i &lt; argc; i++) {
PyObject *pyobj = PyTuple_GetItem(varargs, i); PyObject *pyobj = PyTuple_GetItem(varargs, i);
@ -526,7 +526,7 @@ like this:
PyObject *pystr; PyObject *pystr;
if (!PyUnicode_Check(pyobj)) { if (!PyUnicode_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string"); PyErr_SetString(PyExc_ValueError, "Expected a string");
return NULL; SWIG_fail;
} }
pystr = PyUnicode_AsUTF8String(pyobj); pystr = PyUnicode_AsUTF8String(pyobj);
str = strdup(PyBytes_AsString(pystr)); str = strdup(PyBytes_AsString(pystr));
@ -534,7 +534,7 @@ like this:
%#else %#else
if (!PyString_Check(pyobj)) { if (!PyString_Check(pyobj)) {
PyErr_SetString(PyExc_ValueError, "Expected a string"); PyErr_SetString(PyExc_ValueError, "Expected a string");
return NULL; SWIG_fail;
} }
str = PyString_AsString(pyobj); str = PyString_AsString(pyobj);
%#endif %#endif
@ -635,9 +635,9 @@ example. For example:
for (i = 0; i &lt; argc; i++) { for (i = 0; i &lt; argc; i++) {
PyObject *o = PyTuple_GetItem(varargs, i); PyObject *o = PyTuple_GetItem(varargs, i);
if (!PyString_Check(o)) { if (!PyString_Check(o)) {
PyErr_SetString(PyExc_ValueError,"Expected a string");
free(argv); free(argv);
return NULL; PyErr_SetString(PyExc_ValueError, "Expected a string");
SWIG_fail;
} }
argv[i] = PyString_AsString(o); argv[i] = PyString_AsString(o);
} }
@ -676,11 +676,11 @@ example. For example:
&amp;ffi_type_uint, types) == FFI_OK) { &amp;ffi_type_uint, types) == FFI_OK) {
ffi_call(&amp;cif, (void (*)()) execlp, &amp;result, values); ffi_call(&amp;cif, (void (*)()) execlp, &amp;result, values);
} else { } else {
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
free(types); free(types);
free(values); free(values);
free(arg3); free(arg3);
return NULL; PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
SWIG_fail;
} }
free(types); free(types);
free(values); free(values);
@ -744,8 +744,8 @@ As a more extreme example of libffi, here is some code that attempts to wrap <tt
argv[i].type = VT_POINTER; argv[i].type = VT_POINTER;
argv[i].val.pvalue = (void *) PyString_AsString(o); argv[i].val.pvalue = (void *) PyString_AsString(o);
} else { } else {
PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
free(argv); free(argv);
PyErr_SetString(PyExc_ValueError, "Unsupported argument type");
return NULL; return NULL;
} }
} }
@ -793,11 +793,11 @@ As a more extreme example of libffi, here is some code that attempts to wrap <tt
&amp;ffi_type_uint, types) == FFI_OK) { &amp;ffi_type_uint, types) == FFI_OK) {
ffi_call(&amp;cif, (void (*)()) printf, &amp;result, values); ffi_call(&amp;cif, (void (*)()) printf, &amp;result, values);
} else { } else {
PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
free(types); free(types);
free(values); free(values);
free(args); free(args);
return NULL; PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
SWIG_fail;
} }
free(types); free(types);
free(values); free(values);

View file

@ -327,11 +327,11 @@ else
endif endif
PYTHON_SO = @PYTHON_SO@ PYTHON_SO = @PYTHON_SO@
# SWIG option for Python # SWIG option for Python3
ifeq (,$(PY3)) ifeq (,$(PY3))
SWIGPYTHON = $(SWIG) -python SWIGOPTPY3 =
else else
SWIGPYTHON = $(SWIG) -python -py3 SWIGOPTPY3 = -py3
endif endif
PEP8 = @PEP8@ PEP8 = @PEP8@
@ -342,7 +342,7 @@ PEP8_FLAGS = --ignore=E402,E501,E30,W291,W391
# ---------------------------------------------------------------- # ----------------------------------------------------------------
python: $(SRCDIR_SRCS) python: $(SRCDIR_SRCS)
$(SWIGPYTHON) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH) $(SWIG) -python $(SWIGOPTPY3) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE) $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO) $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
@ -351,7 +351,7 @@ python: $(SRCDIR_SRCS)
# ----------------------------------------------------------------- # -----------------------------------------------------------------
python_cpp: $(SRCDIR_SRCS) python_cpp: $(SRCDIR_SRCS)
$(SWIGPYTHON) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) $(SWIG) -python $(SWIGOPTPY3) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE) $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO) $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
@ -367,12 +367,12 @@ TKINTER =
PYTHON_LIBOPTS = $(PYTHON_LINK) @LIBS@ $(TKINTER) $(SYSLIBS) PYTHON_LIBOPTS = $(PYTHON_LINK) @LIBS@ $(TKINTER) $(SYSLIBS)
python_static: $(SRCDIR_SRCS) python_static: $(SRCDIR_SRCS)
$(SWIGPYTHON) -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH) $(SWIG) -python $(SWIGOPTPY3) -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET) $(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
python_static_cpp: $(SRCDIR_SRCS) python_static_cpp: $(SRCDIR_SRCS)
$(SWIGPYTHON) -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) $(SWIG) -python $(SWIGOPTPY3) -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET) $(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
@ -896,10 +896,10 @@ mzscheme_clean:
##### Ocaml ##### ##### Ocaml #####
################################################################## ##################################################################
OCC=@OCAMLC@ OCC=$(COMPILETOOL) @OCAMLC@
OCAMLDLGEN=@OCAMLDLGEN@ OCAMLDLGEN=$(COMPILETOOL) @OCAMLDLGEN@
OCAMLFIND=@OCAMLFIND@ OCAMLFIND=$(COMPILETOOL) @OCAMLFIND@
OCAMLMKTOP=@OCAMLMKTOP@ $(SWIGWHERE) OCAMLMKTOP=$(COMPILETOOL) @OCAMLMKTOP@ $(SWIGWHERE)
NOLINK ?= false NOLINK ?= false
OCAMLPP= -pp "camlp4o ./swigp4.cmo" OCAMLPP= -pp "camlp4o ./swigp4.cmo"
OCAMLP4WHERE=`$(COMPILETOOL) @CAMLP4@ -where` OCAMLP4WHERE=`$(COMPILETOOL) @CAMLP4@ -where`
@ -910,8 +910,7 @@ OCAMLCORE=\
$(SWIG) -ocaml -co swigp4.ml 2>/dev/null && \ $(SWIG) -ocaml -co swigp4.ml 2>/dev/null && \
$(OCC) -c swig.mli && \ $(OCC) -c swig.mli && \
$(OCC) -c swig.ml && \ $(OCC) -c swig.ml && \
$(OCC) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" \ $(OCC) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
-c swigp4.ml
ocaml_static: $(SRCDIR_SRCS) ocaml_static: $(SRCDIR_SRCS)
$(OCAMLCORE) $(OCAMLCORE)
@ -919,32 +918,20 @@ ocaml_static: $(SRCDIR_SRCS)
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS) $(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
$(OCC) -g -c $(INTERFACE:%.i=%.mli) $(OCC) -g -c $(INTERFACE:%.i=%.mli)
$(OCC) -g -c $(INTERFACE:%.i=%.ml) $(OCC) -g -c $(INTERFACE:%.i=%.ml)
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
$(OCC) $(OCAMLPP) -c $(PROGFILE) $(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
swig.cmo \
$(INTERFACE:%.i=%.cmo) \
$(PROGFILE:%.ml=%.cmo) \
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
ocaml_dynamic: $(SRCDIR_SRCS) ocaml_dynamic: $(SRCDIR_SRCS)
$(OCAMLCORE) $(OCAMLCORE)
$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH) $(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS) $(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) \ $(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS)
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS) $(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \
$(INTERFACE:%.i=%_dynamic.ml)
mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml) mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
rm $(INTERFACE:%.i=%.mli) rm $(INTERFACE:%.i=%.mli)
$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml) $(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
$(OCC) $(OCAMLPP) -c $(PROGFILE) $(NOLINK) || $(OCAMLFIND) $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo)
$(NOLINK) || $(OCAMLFIND) \
$(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
swig.cmo \
-package dl -linkpkg \
$(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo)
ocaml_static_toplevel: $(SRCDIR_SRCS) ocaml_static_toplevel: $(SRCDIR_SRCS)
$(OCAMLCORE) $(OCAMLCORE)
@ -952,72 +939,41 @@ ocaml_static_toplevel: $(SRCDIR_SRCS)
$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS) $(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
$(OCC) -g -c $(INTERFACE:%.i=%.mli) $(OCC) -g -c $(INTERFACE:%.i=%.mli)
$(OCC) -g -c $(INTERFACE:%.i=%.ml) $(OCC) -g -c $(INTERFACE:%.i=%.ml)
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
$(OCC) $(OCAMLPP) -c $(PROGFILE) $(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) camlp4o.cma swigp4.cmo -g -ccopt -g -cclib -g -custom -o $(TARGET)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
$(NOLINK) || $(OCAMLMKTOP) \
swig.cmo \
-I $(OCAMLP4WHERE) camlp4o.cma swigp4.cmo \
-g -ccopt -g -cclib -g -custom -o $(TARGET)_top \
$(INTERFACE:%.i=%.cmo) \
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
ocaml_static_cpp: $(SRCDIR_SRCS) ocaml_static_cpp: $(SRCDIR_SRCS)
$(OCAMLCORE) $(OCAMLCORE)
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) $(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c) cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \ $(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
$(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
$(OCC) -g -c $(INTERFACE:%.i=%.mli) $(OCC) -g -c $(INTERFACE:%.i=%.mli)
$(OCC) -g -c $(INTERFACE:%.i=%.ml) $(OCC) -g -c $(INTERFACE:%.i=%.ml)
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
$(OCC) $(OCAMLPP) -c $(PROGFILE) $(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(TARGET) \
swig.cmo \
$(INTERFACE:%.i=%.cmo) \
$(PROGFILE:%.ml=%.cmo) \
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
-cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
ocaml_static_cpp_toplevel: $(SRCDIR_SRCS) ocaml_static_cpp_toplevel: $(SRCDIR_SRCS)
$(OCAMLCORE) $(OCAMLCORE)
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) $(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c) cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \ $(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
$(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
$(OCC) -g -c $(INTERFACE:%.i=%.mli) $(OCC) -g -c $(INTERFACE:%.i=%.mli)
$(OCC) -g -c $(INTERFACE:%.i=%.ml) $(OCC) -g -c $(INTERFACE:%.i=%.ml)
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
$(OCC) $(OCAMLPP) -c $(PROGFILE) $(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo -g -ccopt -g -cclib -g -custom -o $(TARGET)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
$(NOLINK) || $(OCAMLMKTOP) \
swig.cmo \
-I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo \
-g -ccopt -g -cclib -g -custom -o $(TARGET)_top \
$(INTERFACE:%.i=%.cmo) \
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
-cclib "$(LIBS)" -cc '$(CXX) -Wno-write-strings'
ocaml_dynamic_cpp: $(SRCDIR_SRCS) ocaml_dynamic_cpp: $(SRCDIR_SRCS)
$(OCAMLCORE) $(OCAMLCORE)
$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) $(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c) cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
$(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" \ $(OCC) -cc '$(CXX) -Wno-write-strings' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC
$(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC $(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(CPP_DLLIBS) $(LIBS)
$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) \ $(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
$(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \
$(CPP_DLLIBS) $(LIBS)
$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > \
$(INTERFACE:%.i=%_dynamic.ml)
mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml) mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
rm $(INTERFACE:%.i=%.mli) rm $(INTERFACE:%.i=%.mli)
$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml) $(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
test -z "$(PROGFILE)" || test -f "$(PROGFILE)" && \ test -z "$(PROGFILE)" || $(OCC) $(OCAMLPP) -c $(PROGFILE)
$(OCC) $(OCAMLPP) -c $(PROGFILE) $(NOLINK) || $(OCAMLFIND) swig.cmo $(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom -o $(TARGET) -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX) -Wno-write-strings'
$(NOLINK) || $(OCAMLFIND) \
swig.cmo \
$(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom \
-o $(TARGET) \
-package dl -linkpkg \
$(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX) -Wno-write-strings'
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# Run ocaml example # Run ocaml example
@ -1116,7 +1072,57 @@ ruby_clean:
rm -f *.@OBJEXT@ *$(RUBY_SO) rm -f *.@OBJEXT@ *$(RUBY_SO)
################################################################## ##################################################################
##### PHP ###### ##### PHP5 ######
##################################################################
PHP5 = @PHP5@
PHP5_INCLUDE = @PHP5INC@
PHP5_SO = @PHP5_SO@
PHP5_SCRIPT = $(SRCDIR)$(RUNME).php
# -------------------------------------------------------------------
# Build a PHP5 dynamically loadable module (C)
# -------------------------------------------------------------------
php5: $(SRCDIR_SRCS)
$(SWIG) -php5 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP5_INCLUDE)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP5_SO)
# --------------------------------------------------------------------
# Build a PHP5 dynamically loadable module (C++)
# --------------------------------------------------------------------
php5_cpp: $(SRCDIR_SRCS)
$(SWIG) -php5 -cppext cxx -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP5_INCLUDE)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP5_SO)
# -----------------------------------------------------------------
# Running a PHP5 example
# -----------------------------------------------------------------
php5_run:
$(RUNTOOL) $(PHP5) -n -q -d extension_dir=. -d safe_mode=Off $(PHP5_SCRIPT) $(RUNPIPE)
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
php5_version:
$(PHP5) -v | head -n 1
# -----------------------------------------------------------------
# Cleaning the PHP5 examples
# -----------------------------------------------------------------
php5_clean:
rm -f *_wrap* *~ .~* example.php php_example.h
rm -f core @EXTRA_CLEAN@
rm -f *.@OBJEXT@ *$(PHP5_SO)
##################################################################
##### PHP7 ######
################################################################## ##################################################################
PHP = @PHP@ PHP = @PHP@
@ -1129,7 +1135,7 @@ PHP_SCRIPT = $(SRCDIR)$(RUNME).php
# ------------------------------------------------------------------- # -------------------------------------------------------------------
php: $(SRCDIR_SRCS) php: $(SRCDIR_SRCS)
$(SWIG) -php $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH) $(SWIG) -php7 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP_INCLUDE) $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP_INCLUDE)
$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO) $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
@ -1138,7 +1144,7 @@ php: $(SRCDIR_SRCS)
# -------------------------------------------------------------------- # --------------------------------------------------------------------
php_cpp: $(SRCDIR_SRCS) php_cpp: $(SRCDIR_SRCS)
$(SWIG) -php -cppext cxx -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH) $(SWIG) -php7 -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP_INCLUDE) $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP_INCLUDE)
$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO) $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
@ -1147,7 +1153,7 @@ php_cpp: $(SRCDIR_SRCS)
# ----------------------------------------------------------------- # -----------------------------------------------------------------
php_run: php_run:
$(RUNTOOL) $(PHP) -n -q -d extension_dir=. -d safe_mode=Off $(PHP_SCRIPT) $(RUNPIPE) $(RUNTOOL) $(PHP) -n -q -d extension_dir=. -d safe_mode=Off -d display_errors=stderr $(PHP_SCRIPT) $(RUNPIPE)
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# Version display # Version display

View file

@ -1,6 +1,3 @@
#!./matrix \
-e do-test -s
!#
;;; Authors: David Beazley <beazley@cs.uchicago.edu>, 1999 ;;; Authors: David Beazley <beazley@cs.uchicago.edu>, 1999
;;; Martin Froehlich <MartinFroehlich@ACM.org>, 2000 ;;; Martin Froehlich <MartinFroehlich@ACM.org>, 2000
;;; ;;;

View file

@ -19,6 +19,10 @@ public:
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif #endif
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
#endif
class Test { class Test {
public: public:
@ -50,4 +54,7 @@ public:
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif #endif
#if __GNUC__ >= 7
#pragma GCC diagnostic pop
#endif

View file

@ -19,10 +19,14 @@ public:
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif #endif
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated" // dynamic exception specifications are deprecated in C++11
#endif
class Test { class Test {
public: public:
int simple() throw(int&) { int simple() throw(int) {
throw(37); throw(37);
return 1; return 1;
} }
@ -50,4 +54,7 @@ public:
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
#endif #endif
#if __GNUC__ >= 7
#pragma GCC diagnostic pop
#endif

View file

@ -1,18 +1,18 @@
<html> <html>
<head> <head>
<title>SWIG:Examples:python:simple</title> <title>SWIG:Examples:ocaml:simple</title>
</head> </head>
<body bgcolor="#ffffff"> <body bgcolor="#ffffff">
<tt>SWIG/Examples/python/simple/</tt> <tt>SWIG/Examples/ocaml/simple/</tt>
<hr> <hr>
<H2>Simple Python Example</H2> <H2>Simple Ocaml Example</H2>
<p> <p>
This example illustrates how you can hook Python to a very simple C program containing This example illustrates how you can hook Ocaml to a very simple C program containing
a function and a global variable. a function and a global variable.
<h2>The C Code</h2> <h2>The C Code</h2>
@ -57,7 +57,7 @@ extern double Foo;
<h2>Compilation</h2> <h2>Compilation</h2>
<ol> <ol>
<li><tt>swig -python <a href="example.i">example.i</a></tt> <li><tt>swig -ocaml <a href="example.i">example.i</a></tt>
<p> <p>
<li>Compile <tt><a href="example_wrap.c">example_wrap.c</a></tt> and <tt><a href="example.c">example.c</a></tt> <li>Compile <tt><a href="example_wrap.c">example_wrap.c</a></tt> and <tt><a href="example.c">example.c</a></tt>
to create the extension <tt>examplemodule.so</tt>. to create the extension <tt>examplemodule.so</tt>.
@ -65,29 +65,29 @@ to create the extension <tt>examplemodule.so</tt>.
<h2>Using the extension</h2> <h2>Using the extension</h2>
Click <a href="example.py">here</a> to see a script that calls our C functions from Python. Click <a href="example.ml">here</a> to see a script that calls our C functions from Ocaml.
<h2>Key points</h2> <h2>Key points</h2>
<ul> <ul>
<li>Use the <tt>import</tt> statement to load your extension module from Python. For example: <li>Use the <tt>open</tt> statement to load your extension module from Ocaml. For example:
<blockquote> <blockquote>
<pre> <pre>
import example open Example
</pre> </pre>
</blockquote> </blockquote>
<li>C functions work just like Python functions. For example: <li>C functions work just like Ocaml functions. For example:
<blockquote> <blockquote>
<pre> <pre>
g = example.gcd(42,105) let g = _gcd '(x,y) as int
</pre> </pre>
</blockquote> </blockquote>
<li>C global variables are accessed through a special variable called 'cvar'. For example: <li>C global variable Foo is wrapped as _Foo in ocaml. For example:
<blockquote> <blockquote>
<pre> <pre>
a = example.cvar.Foo let _ = Printf.printf "Foo = %f\n" (_Foo '() as float)
</pre> </pre>
</blockquote> </blockquote>
</ul> </ul>

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
# This file illustrates the cross language polymorphism using directors. # This file illustrates the cross language polymorphism using directors.

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
# This file illustrates the proxy class C++ interface generated # This file illustrates the proxy class C++ interface generated
# by SWIG. # by SWIG.

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
swigexample swigexample

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
swigexample swigexample

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
swigexample swigexample

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
# This file illustrates the cross language polymorphism using directors. # This file illustrates the cross language polymorphism using directors.

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
swigexample swigexample

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
swigexample swigexample

View file

@ -1,3 +1,8 @@
# do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
# Operator overloading example # Operator overloading example
swigexample swigexample

View file

@ -1,4 +1,7 @@
# file: runme_args.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
# load module # load module
clear all; clear all;

View file

@ -1,3 +1,8 @@
# do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
# Operator overloading example # Operator overloading example
swigexample swigexample

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
swigexample; swigexample;

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
# This file illustrates the manipulation of C++ references in Octave # This file illustrates the manipulation of C++ references in Octave

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
swigexample swigexample

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
swigexample swigexample

View file

@ -1,4 +1,7 @@
# file: runme.m # do not dump Octave core
if exist("crash_dumps_octave_core", "builtin")
crash_dumps_octave_core(0);
endif
swigexample swigexample

View file

@ -15,10 +15,5 @@ build:
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' php_cpp_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp php_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_cpp_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php php
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php php
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp php_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_cpp_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp php_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_cpp_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -15,10 +15,5 @@ build:
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \ SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' php_cpp_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php php
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp php_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_cpp_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php php
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php php
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -27,5 +27,6 @@
# This code is inserted into example.php # This code is inserted into example.php
echo \"this was php code\\n\"; echo \"this was php code\\n\";
" "
%pragma(php) version="1.5"
%pragma(php) phpinfo="php_info_print_table_start();" %pragma(php) phpinfo="php_info_print_table_start();"

View file

@ -2,4 +2,5 @@
require "example.php"; require "example.php";
echo "Version - " . ((new ReflectionExtension('example'))->getVersion());
?> ?>

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp php_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_cpp_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp php_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_cpp_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php php
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php_cpp php_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_cpp_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php php
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -16,11 +16,5 @@ build:
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php php
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' \
php_static
clean: clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean $(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php_clean

View file

@ -0,0 +1,19 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS = -lm
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php5_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_clean

View file

@ -0,0 +1,4 @@
/* File : example.cxx */
#include "example.h"

View 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(); }
};

View file

@ -0,0 +1,11 @@
/* File : example.i */
%module(directors="1") example
%{
#include "example.h"
%}
/* turn on director wrapping Callback */
%feature("director") Callback;
%include "example.h"

View file

@ -0,0 +1,19 @@
<html>
<head>
<title>SWIG:Examples:php5:callback</title>
</head>
<body bgcolor="#ffffff">
<tt>SWIG/Examples/php5/callback/</tt>
<hr>
<H2>Implementing C++ callbacks in PHP5</H2>
<p>
This example illustrates how to use directors to implement C++ callbacks in PHP5.
<hr>
</body>
</html>

View 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";
?>

19
Examples/php5/check.list Normal file
View file

@ -0,0 +1,19 @@
# see top-level Makefile.in
# (see also top-level configure.ac kludge)
callback
class
constants
cpointer
disown
enum
extend
funcptr
overloading
pointer
pragmas
proxy
reference
simple
sync
value
variables

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php5_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_clean

View file

@ -0,0 +1,28 @@
/* File : example.cxx */
#include "example.h"
#define M_PI 3.14159265358979323846
/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
x += dx;
y += dy;
}
int Shape::nshapes = 0;
double Circle::area() {
return M_PI*radius*radius;
}
double Circle::perimeter() {
return 2*M_PI*radius;
}
double Square::area() {
return width*width;
}
double Square::perimeter() {
return 4*width;
}

View file

@ -0,0 +1,34 @@
/* File : example.h */
class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
}
double x, y;
void move(double dx, double dy);
virtual double area() = 0;
virtual double perimeter() = 0;
static int nshapes;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { }
virtual double area();
virtual double perimeter();
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { }
virtual double area();
virtual double perimeter();
};

View file

@ -0,0 +1,9 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%include "example.h"

View file

@ -0,0 +1,60 @@
<?php
# 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\n";
$s = new Square(10);
print " Created square\n";
# ----- Access a static member -----
print "\nA total of " . Shape::nshapes() . " shapes were created\n";
# ----- Member data access -----
# Set the location of the object.
# Note: methods in the base class Shape are used since
# x and y are defined there.
$c->x = 20;
$c->y = 30;
$s->x = -10;
$s->y = 5;
print "\nHere is their current position:\n";
print " Circle = ({$c->x},{$c->y})\n";
print " Square = ({$s->x},{$s->y})\n";
# ----- Call some methods -----
# Notice how the Shape_area() and Shape_perimeter() functions really
# invoke the appropriate virtual method on each object.
print "\nHere are some properties of the shapes:\n";
foreach (array($c,$s) as $o) {
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
$c = NULL;
$s = NULL;
# and don't forget the $o from the for loop above. It still refers to
# the square.
$o = NULL;
print Shape::nshapes() . " shapes remain\n";
print "Goodbye\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS =
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php5
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_clean

View file

@ -0,0 +1,26 @@
/* File : example.i */
%module example
/* A few preprocessor macros */
#define ICONST 42
#define FCONST 2.1828
#define CCONST 'x'
#define CCONST2 '\n'
#define SCONST "Hello World"
#define SCONST2 "\"Hello World\""
/* This should work just fine */
#define EXPR ICONST + 3*(FCONST)
/* This shouldn't do anything */
#define EXTERN extern
/* Neither should this (BAR isn't defined) */
#define FOO (ICONST + BAR)
/* The following statements also produce constants */
%constant int iconst = 37;
%constant double fconst = 3.14;

View file

@ -0,0 +1,28 @@
<?php
require "example.php";
print "ICONST = " . ICONST . " (should be 42)\n";
print "FCONST = " . FCONST . " (should be 2.1828)\n";
print "CCONST = " . CCONST . " (should be 'x')\n";
print "CCONST2 = " . CCONST2 . " (this should be on a new line)\n";
print "SCONST = " . SCONST . " (should be 'Hello World')\n";
print "SCONST2 = " . SCONST2 . " (should be '\"Hello World\"')\n";
print "EXPR = " . EXPR . " (should be 48.5484)\n";
print "iconst = " . iconst . " (should be 37)\n";
print "fconst = " . fconst . " (should be 3.14)\n";
if (EXTERN!="EXTERN") {
print "EXTERN = " . EXTERN . " (Arg! This shouldn't print anything)\n";
} else {
print "EXTERN defaults to 'EXTERN', it probably isn't defined (good)\n";
}
if (FOO!="FOO") {
print "FOO = " . FOO . "(Arg! This shouldn't print anything)\n";
} else {
print "FOO defaults to 'FOO', it probably isn't defined (good)\n";
}
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php5
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_clean

View file

@ -0,0 +1,16 @@
/* File : example.c */
void add(int *x, int *y, int *result) {
*result = *x + *y;
}
void sub(int *x, int *y, int *result) {
*result = *x - *y;
}
int divide(int n, int d, int *r) {
int q;
q = n/d;
*r = n - q*d;
return q;
}

View file

@ -0,0 +1,31 @@
/* File : example.i */
%module example
%{
extern void add(int *, int *, int *);
extern void sub(int *, int *, int *);
%}
/* This example illustrates a couple of different techniques
for manipulating C pointers */
/* First we'll use the pointer library */
extern void add(int *x, int *y, int *result);
%include cpointer.i
%pointer_functions(int, intp);
/* Next we'll use some typemaps */
%include typemaps.i
extern void sub(int *INPUT, int *INPUT, int *OUTPUT);
/* Next we'll use typemaps and the %apply directive */
//%apply int *OUTPUT { int *r };
//extern int divide(int n, int d, int *r);

View file

@ -0,0 +1,47 @@
<?php
require "example.php";
# First create some objects using the pointer library.
print "Testing the pointer library\n";
$a = example::new_intp();
$b = example::new_intp();
$c = example::new_intp();
example::intp_assign($a,37);
example::intp_assign($b,42);
print " a = $a\n";
print " b = $b\n";
print " c = $c\n";
# Call the add() function wuth some pointers
example::add($a,$b,$c);
# Now get the result
$r = example::intp_value($c);
print " 37 + 42 = $r\n";
# Clean up the pointers
example::delete_intp($a);
example::delete_intp($b);
example::delete_intp($c);
# Now try the typemap library
# This should be much easier. Now how it is no longer
# necessary to manufacture pointers.
print "Trying the typemap library\n";
$r = example::sub(37,42);
print " 37 - 42 = $r\n";
# Now try the version with multiple return values
# print "Testing multiple return values\n";
# $a = example::divide(42,37);
# $q = $a[0]
# $r = $a[1]
# print " 42/37 = $q remainder $r\n";
?>

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS =
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \
php5_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' php5_clean

View file

@ -0,0 +1,51 @@
/* File : example.c */
#include "example.h"
#include <math.h>
#ifndef M_PI
# define M_PI 3.14159265358979323846
#endif
int Shape::get_nshapes() {
return nshapes;
}
/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
x += dx;
y += dy;
}
int Shape::nshapes = 0;
void Circle::set_radius( double r ) {
radius = r;
}
double Circle::area(void) {
return M_PI*radius*radius;
}
double Circle::perimeter(void) {
return 2*M_PI*radius;
}
double Square::area(void) {
return width*width;
}
double Square::perimeter(void) {
return 4*width;
}
ShapeContainer::~ShapeContainer() {
iterator i=shapes.begin();
for( iterator i = shapes.begin(); i != shapes.end(); ++i ) {
delete *i;
}
}
void
ShapeContainer::addShape( Shape *s ) {
shapes.push_back( s );
}

View file

@ -0,0 +1,50 @@
/* File : example.h */
#include <vector>
class Shape {
public:
Shape() {
nshapes++;
}
virtual ~Shape() {
nshapes--;
}
double x, y;
void move(double dx, double dy);
virtual double area(void) = 0;
virtual double perimeter(void) = 0;
static int nshapes;
static int get_nshapes();
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { }
~Circle() { }
void set_radius( double r );
virtual double area(void);
virtual double perimeter(void);
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { }
~Square() { }
virtual double area(void);
virtual double perimeter(void);
};
class ShapeContainer {
private:
typedef std::vector<Shape*>::iterator iterator;
std::vector<Shape*> shapes;
public:
ShapeContainer() : shapes() {}
~ShapeContainer();
void addShape( Shape *s );
};

View file

@ -0,0 +1,12 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
%apply SWIGTYPE *DISOWN {(Shape *s)};
/* Let's just grab the original header file here */
%include "example.h"

View file

@ -0,0 +1,49 @@
<?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.
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";
# ----- Create the ShapeContainer ----
$container = new ShapeContainer();
$container->addShape($c);
$container->addShape($s);
# ----- Access a static member -----
print "\nA total of " . Shape::nshapes() . " shapes were created\n";
# ----- Delete by the old references -----
# This should not truely delete the shapes because they are now owned
# by the ShapeContainer.
print "Delete the old references.";
# Note: this invokes the virtual destructor
$c = NULL;
$s = NULL;
print "\nA total of " . Shape::nshapes() . " shapes remain\n";
# ----- Delete by the container -----
# This should truely delete the shapes
print "Delete the container.";
$container = NULL;
print "\nA total of " . Shape::nshapes() . " shapes remain\n";
print "Goodbye\n";
?>

Some files were not shown because too many files have changed in this diff Show more