Merge branch 'master' into javalist
This commit is contained in:
commit
4db1300622
798 changed files with 26703 additions and 7774 deletions
153
.travis.yml
153
.travis.yml
|
|
@ -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
|
|
||||||
|
|
|
||||||
8
ANNOUNCE
8
ANNOUNCE
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
492
CHANGES
|
|
@ -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 ***
|
||||||
|
|
||||||
|
|
|
||||||
135
CHANGES.current
135
CHANGES.current
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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 <class T> swap(T& a, T& 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 <class T> swap(T& a, T& 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&& as an argument) and
|
|
||||||
operator=(ClassType&&):</P>
|
|
||||||
<PRE>class MyClass {
|
|
||||||
MyClass(MyClass&& p) : ptr(p.ptr) {p.ptr = 0;}
|
|
||||||
MyClass& operator=(MyClass&& 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&& to Swig parser. Added testcase
|
|
||||||
cpp11_rvalue_reference.i. Operator && is treated the same as
|
|
||||||
operator &. 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 "return expr",
|
|
||||||
where expr is a constant expression.
|
|
||||||
</P>
|
|
||||||
<P>A keyword "constexpr" 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 "final"
|
|
||||||
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<MyClass>;'. 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<T>. New symbols {} are introduced for the
|
|
||||||
initializer lists.
|
|
||||||
</P>
|
|
||||||
<P>One can now use:
|
|
||||||
</P>
|
|
||||||
<PRE> class A {
|
|
||||||
public:
|
|
||||||
A( std::initializer_list<int> );
|
|
||||||
};
|
|
||||||
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 {"SomeName", 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) -> 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 '->' 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<int> someList;
|
|
||||||
int total = 0;
|
|
||||||
std::for_each( someList.begin(), someList.end(), [&total](int x) {total += x} );
|
|
||||||
std::cout << total;</PRE><P>
|
|
||||||
Parameters inside the [] are the visible parameters of the lambda
|
|
||||||
functions. These can be & (references), = (copies), variable name
|
|
||||||
(variable copy), &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->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< typename LHS, typename RHS>
|
|
||||||
decltype(lhs+rhs) AddingFunc(const LHS &lhs, const RHS &rhs) {return lhs + rhs;} //Not legal C++11</PRE><P>
|
|
||||||
The solution C++11 offers is the combination of the 'auto' keyword
|
|
||||||
before and '-> rettype' after the function declaration:</P>
|
|
||||||
<PRE>template< typename LHS, typename RHS>
|
|
||||||
auto AddingFunc(const LHS &lhs, const RHS &rhs) -> 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) -> int;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto SomeStruct::FuncName(int x, int y) -> int {
|
|
||||||
return x + y;
|
|
||||||
}</PRE><P>
|
|
||||||
Done: Added support for the 'auto' return type. Added support for the
|
|
||||||
'-> 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 "concepts". 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&id=LessThanComparable">?</A>
|
|
||||||
instead of "class" or "typename"):
|
|
||||||
</P>
|
|
||||||
<PRE> template<LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A> T>
|
|
||||||
const T& min(const T &x, const T &y) {
|
|
||||||
return y < x ? y : x;
|
|
||||||
}</PRE><P>
|
|
||||||
Extended syntax (requires conditions are separated with &&,
|
|
||||||
|| or !):
|
|
||||||
</P>
|
|
||||||
<PRE> template< typename T> requires LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A><T>
|
|
||||||
const T& min(const T &x, const T &y) {
|
|
||||||
return y < 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&id=LessThanComparable">?</A>< typename T > {
|
|
||||||
bool operator<(T,T);
|
|
||||||
requires GreaterThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=GreaterThanComparable">?</A><T>;
|
|
||||||
typename value_type;
|
|
||||||
typename reference;
|
|
||||||
};</PRE><P>
|
|
||||||
Concept maps allow usage of a specific type:
|
|
||||||
</P>
|
|
||||||
<PRE> template< typename T>
|
|
||||||
concept_map InputIterator<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=InputIterator">?</A><T*> {
|
|
||||||
typedef T value_type ;
|
|
||||||
typedef T& 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< typename X> {
|
|
||||||
typename value_type;
|
|
||||||
void push(X&, const value_type&);
|
|
||||||
void pop(X&);
|
|
||||||
value_type top(const X&);
|
|
||||||
bool empty(const X&);
|
|
||||||
};
|
|
||||||
template< typename T>
|
|
||||||
concept_map Stack<std::vector<T> > {
|
|
||||||
typedef T value_type;
|
|
||||||
void push(std::vector<T>& v, const T& x) { v.push_back(x); }
|
|
||||||
void pop(std::vector<T>& v) { v.pop_back(); }
|
|
||||||
T top(const std::vector<T>& v) { return v.back(); }
|
|
||||||
bool empty(const std::vector<T>& 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< typename Op, typename T> : CopyConstructible<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=CopyConstructible">?</A><T> {
|
|
||||||
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 <cstddef>.
|
|
||||||
</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 "int".
|
|
||||||
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
|
|
||||||
"Approach 1". 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 "explicit" 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< typename first, typename second, int third>
|
|
||||||
class SomeType;
|
|
||||||
|
|
||||||
template< typename second>
|
|
||||||
typedef SomeType<OtherType, second, 5> 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< typename first, typename second, int third>
|
|
||||||
class SomeType;
|
|
||||||
|
|
||||||
template< typename second>
|
|
||||||
using TypedefName = SomeType<OtherType, second, 5>;</PRE><P>
|
|
||||||
Here we created a new wrapper TypedefName taking one template
|
|
||||||
argument <second> which creates a type SomeType<OtherType,
|
|
||||||
second, 5>. 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<int> 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<typename... Values> class tuple;</PRE><P>
|
|
||||||
This can be used for example:</P>
|
|
||||||
<PRE STYLE="margin-bottom: 0.5cm">class tuple<int, std::vector<int>, std::map<std::string, std::vector<int>>> 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 == '%' && *(++s) != '%')
|
|
||||||
throw std::runtime_error("invalid format string: missing arguments");
|
|
||||||
std::cout << *s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename... Args>
|
|
||||||
void printf(const char* s, T value, Args... args) { // recursive action – split previous args to value + args
|
|
||||||
while (*s) {
|
|
||||||
if (*s == '%' && *(++s) != '%') {
|
|
||||||
std::cout << value;
|
|
||||||
printf(*s ? ++s : s, args...); // call even when *s == 0 to detect extra arguments
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::cout << *s++;
|
|
||||||
}
|
|
||||||
throw std::logic_error("extra arguments provided to printf");
|
|
||||||
}</PRE><P>
|
|
||||||
The tricky part is that variadic templates can unpack actually
|
|
||||||
anywhere – including the class inheritance :(</P>
|
|
||||||
<PRE>template <typename... BaseClasses> class ClassName : public BaseClasses... {
|
|
||||||
public:
|
|
||||||
|
|
||||||
ClassName (BaseClasses&&... 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<typename ...Args> struct SomeStruct {
|
|
||||||
static const int size = sizeof...(Args);
|
|
||||||
}
|
|
||||||
// SomeStruct<Type1, Type2>::size is 2 and SomeStruct<>::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"DELIMITER[, ]DELIMITER" 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 = "hello"_mySuffix;
|
|
||||||
</P>
|
|
||||||
<P>The syntax is similar to other operator overloading functions:
|
|
||||||
</P>
|
|
||||||
<PRE STYLE="margin-bottom: 0.5cm"> OutputType operator "" _mySuffix(const char * string_values);</PRE><P>
|
|
||||||
The null terminated const char* is the string between the "".
|
|
||||||
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 "" _mySuffix(const char * string_values, size_t num_chars);
|
|
||||||
OutputType operator "" _mySuffix(const wchar_t * string_values, size_t num_chars);
|
|
||||||
OutputType operator "" _mySuffix(const char16_t * string_values, size_t num_chars);
|
|
||||||
OutputType operator "" _mySuffix(const char32_t * string_values, size_t num_chars);
|
|
||||||
OutputType operator "" _mySuffix(int value); /* cooked version - ie. atoi() of string */</PRE><P>
|
|
||||||
Another possibility is to use variadic templates:
|
|
||||||
</P>
|
|
||||||
<PRE> template<char...> OutputType operator "" _mySuffix();
|
|
||||||
OutputType someVariable = "1234"_mySuffix;</PRE><P>
|
|
||||||
This instantiates the literal processing function as
|
|
||||||
operator""_Suffix<'1', '2', '3', '4'>. 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 "thread_local" which marks
|
|
||||||
the following variable dynamically located depending on the current
|
|
||||||
thread when using the address-of (&) operator.
|
|
||||||
</P>
|
|
||||||
<P>Syntax:
|
|
||||||
</P>
|
|
||||||
<PRE> struct A {
|
|
||||||
thread_local int val;
|
|
||||||
};</PRE><P>
|
|
||||||
Done: Add "thread_local" 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 "default" and "delete" are introduced.
|
|
||||||
The syntax is similar to declaration of pure virtual function:
|
|
||||||
</P>
|
|
||||||
<PRE> struct NonCopyable {
|
|
||||||
NonCopyable & operator=(const NonCopyable&) = delete; /* Removes operator= */
|
|
||||||
NonCopyable(const NonCopyable&) = 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<class T> void f(T) = delete; /* Only accept int */
|
|
||||||
};</PRE><P>
|
|
||||||
Ignored: Swig already parses the keywords "= delete" and "=
|
|
||||||
default". 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 <typename T>
|
|
||||||
struct Check {
|
|
||||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
|
||||||
};</PRE><P>
|
|
||||||
Done: Added syntax support for "static_assert()". 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 <class ...Types> class tuple;</PRE><P>
|
|
||||||
Constructor is automatically generated filling the tuple elements.
|
|
||||||
get<X> function is introduced to get the Xth element in the
|
|
||||||
tuple.</P>
|
|
||||||
<PRE>typedef tuple< int, double, long &, const char * > test_tuple ;
|
|
||||||
long lengthy = 12 ;
|
|
||||||
test_tuple proof( 18, 6.5, lengthy, "Ciao!" ) ;
|
|
||||||
lengthy = get<0>(proof) ; // Assign to 'lengthy' the value 18.
|
|
||||||
get<3>(proof) = " Beautiful!" ; // 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< int , double, string > tuple_1 t1 ;
|
|
||||||
typedef tuple< char, short , const char * > tuple_2 t2( 'X', 2, "Hola!" ) ;
|
|
||||||
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<> class.</P>
|
|
||||||
<H2>Hash tables [TODO]</H2>
|
|
||||||
<P>C++11 introduces the "unordered" 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 "unordered" 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 <utility>) 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<int ( int, int )> 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 <type_traits> 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< int B, int N >
|
|
||||||
struct Pow {
|
|
||||||
// recursive call and recombination.
|
|
||||||
enum{ value = B*Pow< B, N-1 >::value };
|
|
||||||
};
|
|
||||||
template< int B > struct Pow< B, 0 > // <EM>N == 0</EM> condition of termination.
|
|
||||||
{
|
|
||||||
enum{ value = 1 };
|
|
||||||
};
|
|
||||||
int quartic_of_three = Pow< 3, 4 >::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< bool B > struct algorithm {
|
|
||||||
template< class T1, class T2 > int do_it( T1 &, T2 & ) { /*...*/ }
|
|
||||||
};
|
|
||||||
// Second way of operating.
|
|
||||||
template<> struct algorithm<true> {
|
|
||||||
template< class T1, class T2 > int do_it( T1, T2 ) { /*...*/ }
|
|
||||||
};
|
|
||||||
// Instantiating 'elaborate' will automatically instantiate the correct way to operate.
|
|
||||||
template< class T1, class T2 > 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< is_integral<T1>::value && is_floating_point<T2>::value >::do_it( A, B );
|
|
||||||
}</PRE><P>
|
|
||||||
Swig correctly parses the syntax for template<bool>,
|
|
||||||
template<class T> and template<>.
|
|
||||||
</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< class Obj >
|
|
||||||
class calculus_ver2 {
|
|
||||||
public:
|
|
||||||
template< class Arg >
|
|
||||||
typename std::result_of<Obj(Arg)>::type operator()( Arg& 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>
|
|
||||||
|
|
@ -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< typename T1, typename T2, int >
|
|
||||||
class SomeType {
|
|
||||||
public:
|
|
||||||
T1 a;
|
|
||||||
T2 b;
|
|
||||||
int c;
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename T2 >
|
|
||||||
using TypedefName = SomeType<char*, T2, 5>;
|
|
||||||
</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< typename T1, typename T2, int N >
|
||||||
|
class SomeType {
|
||||||
|
public:
|
||||||
|
T1 a;
|
||||||
|
T2 b;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T2 >
|
||||||
|
using TypedefName = SomeType<char*, T2, 5>;
|
||||||
|
</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<char*, bool, 5>;
|
||||||
|
%template() TypedefName<bool>;
|
||||||
|
</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>
|
||||||
|
|
|
||||||
|
|
@ -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 &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>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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 -->
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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 <Foo> 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
|
||||||
|
|
|
||||||
|
|
@ -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->ExceptionClear();
|
jenv->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<typename T> struct Value {
|
||||||
|
T value;
|
||||||
|
Value(const T& 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<unsigned int>;
|
||||||
|
</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->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->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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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& v) {return v*s;}
|
inline Test operator* (float s, const Test& v) {return v*s;}
|
||||||
|
|
||||||
|
|
||||||
inline std::ostream& operator<< (std::ostream& o, const Test& v)
|
inline std::ostream& operator<< (std::ostream& o, const Test& v)
|
||||||
{
|
{
|
||||||
return o << "(" << v.x << ")";
|
return o << "(" << v.x << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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>
|
||||||
|
|
|
||||||
|
|
@ -1095,8 +1095,9 @@ Now we extend it with some new code
|
||||||
sprintf(tmp, "Complex(%g, %g)", $self->re(), $self->im());
|
sprintf(tmp, "Complex(%g, %g)", $self->re(), $self->im());
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
bool operator==(const Complex& c)
|
bool operator==(const Complex& c) {
|
||||||
{ return ($self->re()==c.re() && $self->im()==c.im());}
|
return ($self->re()==c.re() && $self->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>
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &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 **) &$1, $1_descriptor,0)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$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 **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -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 < 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 < 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>-></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">
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:<slot>"),
|
||||||
|
where <slot> 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 >= 0x03020000
|
||||||
|
static Py_hash_t myHashFunc(PyObject *pyobj)
|
||||||
|
#else
|
||||||
|
static long myHashFunc(PyObject *pyobj)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
MyClass *cobj;
|
||||||
|
// Convert pyobj to cobj
|
||||||
|
return (cobj->field1 * (cobj->field2 << 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 < 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 &e) {
|
} catch (std::out_of_range &e) {
|
||||||
PyErr_SetString(PyExc_IndexError, const_cast<char*>(e.what()));
|
PyErr_SetString(PyExc_IndexError, const_cast<char*>(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 < 0) {
|
if ($1 < 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 < size; i++) {
|
for (i = 0; i < 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 < $1; i++) {
|
for (i = 0; i < $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 = &temp[0];
|
$1 = &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 < $1_dim0; i++) {
|
for (i =0; i < $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 = &temp[0];
|
$1 = &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 **) &f, SWIGTYPE_p_Foo, SWIG_POINTER_EXCEPTION) == -1)
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &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 **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION)) == -1)
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$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 **) &$1, $descriptor(Foo *),
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$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 >= (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 <pybuffer.i>
|
%include <pybuffer.i>
|
||||||
%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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
> 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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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 <ifile>
|
||||||
-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 <outfile>
|
-o <em>outfile</em> Set name of C/C++ output file to <outfile>
|
||||||
-oh <em>headfile</em> Set name of C++ output header file for directors to <headfile>
|
-oh <em>headfile</em> Set name of C++ output header file for directors to <headfile>
|
||||||
-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>
|
||||||
|
|
|
||||||
|
|
@ -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 <std_string.i>
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
class ExtendMe {
|
||||||
|
public:
|
||||||
|
template <typename T>
|
||||||
|
T do_stuff_impl(int a, T b, double d) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%extend ExtendMe {
|
||||||
|
template<typename T>
|
||||||
|
T do_overloaded_stuff(T b) {
|
||||||
|
return $self->do_stuff_impl(0, b, 4.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff<std::string>;
|
||||||
|
%template(do_overloaded_stuff) ExtendMe::do_overloaded_stuff<double>;
|
||||||
|
</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
|
||||||
|
|
|
||||||
|
|
@ -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 <gateway_id></td>
|
<td>Generate the gateway XML with the given <gateway_id></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>:
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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, &len);
|
$1 = Tcl_GetStringFromObj(interp, &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 **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &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 **) &$1, $1_descriptor,0)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$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 **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $descriptor(Foo *), 0))) {
|
||||||
|
SWIG_exception_fail(SWIG_TypeError, "in method '$symname', expecting type Foo");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -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 < 0) {
|
if ($1 < 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 < 4; i++) {
|
for (i = 0; i < 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 < $1_dim0; i++) {
|
for (i = 0; i < $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 < $1_dim0; i++) {
|
for (i = 0; i < $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 < 0) {
|
if ($2 < 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("<limits.h>", "header") {
|
%fragment("<limits.h>", "header") %{
|
||||||
%#include <limits.h>
|
#include <limits.h>
|
||||||
}
|
%}
|
||||||
|
|
||||||
|
|
||||||
%fragment("AsMyClass", "header", fragment="<limits.h>") {
|
%fragment("AsMyClass", "header", fragment="<limits.h>") {
|
||||||
|
|
@ -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("<limits.h>", "header") %{
|
||||||
|
#include <limits.h>
|
||||||
|
%}
|
||||||
|
|
||||||
|
struct X {
|
||||||
|
...
|
||||||
|
%extend {
|
||||||
|
%fragment("<limits.h>");
|
||||||
|
bool check(short val) {
|
||||||
|
if (val < SHRT_MIN /*defined in <limits.h>*/) {
|
||||||
|
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 <stdio.h>
|
||||||
|
%}
|
||||||
|
%fragment("<limits.h>");
|
||||||
|
</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 <stdio.h>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
</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 **) &arg1, SWIGTYPE_p_Foo,1)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr(obj0, (void **) &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 **) &$1, $1_descriptor)) == -1) return NULL;
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$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 **) &$1, $1_descriptor)) == -1) {
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 0))) {
|
||||||
Bar *temp;
|
Bar *temp;
|
||||||
if ((SWIG_ConvertPtr($input, (void **) &temp, <b>$descriptor(Bar *)</b>) == -1) {
|
if (!SWIG_IsOK(SWIG_ConvertPtr($input, (void **) &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 &, SWIGTYPE [] {
|
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, noblock=1) SWIGTYPE * {
|
||||||
void *ptr;
|
void *vptr = 0;
|
||||||
if (SWIG_ConvertPtr($input, (void **) &ptr, $1_descriptor, 0) == -1) {
|
int res = SWIG_ConvertPtr($input, &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 **) &ptr, $&1_descriptor, 0) == -1) {
|
|
||||||
$1 = 0;
|
|
||||||
PyErr_Clear();
|
|
||||||
} else {
|
|
||||||
$1 = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
%typecheck(SWIG_TYPECHECK_VOIDPTR) void * {
|
|
||||||
void *ptr;
|
|
||||||
if (SWIG_ConvertPtr($input, (void **) &ptr, 0, 0) == -1) {
|
|
||||||
$1 = 0;
|
|
||||||
PyErr_Clear();
|
|
||||||
} else {
|
|
||||||
$1 = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
%typecheck(SWIG_TYPECHECK_POINTER) PyObject *
|
|
||||||
{
|
|
||||||
$1 = ($input != 0);
|
$1 = ($input != 0);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
|
||||||
|
|
@ -517,7 +517,7 @@ like this:
|
||||||
argc = PyTuple_Size(varargs);
|
argc = PyTuple_Size(varargs);
|
||||||
if (argc > 10) {
|
if (argc > 10) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
PyErr_SetString(PyExc_ValueError, "Too many arguments");
|
||||||
return NULL;
|
SWIG_fail;
|
||||||
}
|
}
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < 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 < argc; i++) {
|
for (i = 0; i < 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:
|
||||||
&ffi_type_uint, types) == FFI_OK) {
|
&ffi_type_uint, types) == FFI_OK) {
|
||||||
ffi_call(&cif, (void (*)()) execlp, &result, values);
|
ffi_call(&cif, (void (*)()) execlp, &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
|
||||||
&ffi_type_uint, types) == FFI_OK) {
|
&ffi_type_uint, types) == FFI_OK) {
|
||||||
ffi_call(&cif, (void (*)()) printf, &result, values);
|
ffi_call(&cif, (void (*)()) printf, &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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
;;;
|
;;;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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();"
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
require "example.php";
|
require "example.php";
|
||||||
|
|
||||||
|
echo "Version - " . ((new ReflectionExtension('example'))->getVersion());
|
||||||
?>
|
?>
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
19
Examples/php5/callback/Makefile
Normal file
19
Examples/php5/callback/Makefile
Normal 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
|
||||||
4
Examples/php5/callback/example.cxx
Normal file
4
Examples/php5/callback/example.cxx
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
/* File : example.cxx */
|
||||||
|
|
||||||
|
#include "example.h"
|
||||||
|
|
||||||
22
Examples/php5/callback/example.h
Normal file
22
Examples/php5/callback/example.h
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* File : example.h */
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class Callback {
|
||||||
|
public:
|
||||||
|
virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
|
||||||
|
virtual void run() { std::cout << "Callback::run()" << std::endl; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Caller {
|
||||||
|
private:
|
||||||
|
Callback *_callback;
|
||||||
|
public:
|
||||||
|
Caller(): _callback(0) {}
|
||||||
|
~Caller() { delCallback(); }
|
||||||
|
void delCallback() { delete _callback; _callback = 0; }
|
||||||
|
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
|
||||||
|
void call() { if (_callback) _callback->run(); }
|
||||||
|
};
|
||||||
|
|
||||||
11
Examples/php5/callback/example.i
Normal file
11
Examples/php5/callback/example.i
Normal 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"
|
||||||
|
|
||||||
19
Examples/php5/callback/index.html
Normal file
19
Examples/php5/callback/index.html
Normal 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>
|
||||||
47
Examples/php5/callback/runme.php
Normal file
47
Examples/php5/callback/runme.php
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
# This file illustrates the cross language polymorphism using directors.
|
||||||
|
|
||||||
|
require("example.php");
|
||||||
|
|
||||||
|
# Class, which overwrites Callback::run().
|
||||||
|
|
||||||
|
class PhpCallback extends Callback {
|
||||||
|
function run() {
|
||||||
|
print "PhpCallback.run()\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# Create an Caller instance
|
||||||
|
|
||||||
|
$caller = new Caller();
|
||||||
|
|
||||||
|
# Add a simple C++ callback (caller owns the callback, so
|
||||||
|
# we disown it first by clearing the .thisown flag).
|
||||||
|
|
||||||
|
print "Adding and calling a normal C++ callback\n";
|
||||||
|
print "----------------------------------------\n";
|
||||||
|
|
||||||
|
$callback = new Callback();
|
||||||
|
$callback->thisown = 0;
|
||||||
|
$caller->setCallback($callback);
|
||||||
|
$caller->call();
|
||||||
|
$caller->delCallback();
|
||||||
|
|
||||||
|
print "\n";
|
||||||
|
print "Adding and calling a PHP callback\n";
|
||||||
|
print "------------------------------------\n";
|
||||||
|
|
||||||
|
# Add a PHP callback.
|
||||||
|
|
||||||
|
$callback = new PhpCallback();
|
||||||
|
$callback->thisown = 0;
|
||||||
|
$caller->setCallback($callback);
|
||||||
|
$caller->call();
|
||||||
|
$caller->delCallback();
|
||||||
|
|
||||||
|
# All done.
|
||||||
|
|
||||||
|
print "php exit\n";
|
||||||
|
|
||||||
|
?>
|
||||||
19
Examples/php5/check.list
Normal file
19
Examples/php5/check.list
Normal 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
|
||||||
20
Examples/php5/class/Makefile
Normal file
20
Examples/php5/class/Makefile
Normal 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
|
||||||
28
Examples/php5/class/example.cxx
Normal file
28
Examples/php5/class/example.cxx
Normal 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;
|
||||||
|
}
|
||||||
34
Examples/php5/class/example.h
Normal file
34
Examples/php5/class/example.h
Normal 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();
|
||||||
|
};
|
||||||
9
Examples/php5/class/example.i
Normal file
9
Examples/php5/class/example.i
Normal 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"
|
||||||
60
Examples/php5/class/runme.php
Normal file
60
Examples/php5/class/runme.php
Normal 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";
|
||||||
|
|
||||||
|
?>
|
||||||
20
Examples/php5/constants/Makefile
Normal file
20
Examples/php5/constants/Makefile
Normal 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
|
||||||
26
Examples/php5/constants/example.i
Normal file
26
Examples/php5/constants/example.i
Normal 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;
|
||||||
|
|
||||||
|
|
||||||
28
Examples/php5/constants/runme.php
Normal file
28
Examples/php5/constants/runme.php
Normal 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";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
20
Examples/php5/cpointer/Makefile
Normal file
20
Examples/php5/cpointer/Makefile
Normal 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
|
||||||
16
Examples/php5/cpointer/example.c
Normal file
16
Examples/php5/cpointer/example.c
Normal 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;
|
||||||
|
}
|
||||||
31
Examples/php5/cpointer/example.i
Normal file
31
Examples/php5/cpointer/example.i
Normal 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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
47
Examples/php5/cpointer/runme.php
Normal file
47
Examples/php5/cpointer/runme.php
Normal 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";
|
||||||
|
|
||||||
|
?>
|
||||||
20
Examples/php5/disown/Makefile
Normal file
20
Examples/php5/disown/Makefile
Normal 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
|
||||||
51
Examples/php5/disown/example.cxx
Normal file
51
Examples/php5/disown/example.cxx
Normal 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 );
|
||||||
|
}
|
||||||
50
Examples/php5/disown/example.h
Normal file
50
Examples/php5/disown/example.h
Normal 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 );
|
||||||
|
};
|
||||||
12
Examples/php5/disown/example.i
Normal file
12
Examples/php5/disown/example.i
Normal 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"
|
||||||
|
|
||||||
49
Examples/php5/disown/runme.php
Normal file
49
Examples/php5/disown/runme.php
Normal 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
Loading…
Add table
Add a link
Reference in a new issue