From: stevenj Date: Wed, 2 Jun 2010 06:22:44 +0000 (-0400) Subject: first stab at SWIG wrappers (unfinished Makefile), starting with Guile X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=584ec8edafa66338bb71f4edb9d162f82128a603;p=nlopt.git first stab at SWIG wrappers (unfinished Makefile), starting with Guile darcs-hash:20100602062244-c8de0-d776ad5f27c68cc6b6d5799d341d4bb0b0264c58.gz --- diff --git a/swig/Makefile.am b/swig/Makefile.am new file mode 100644 index 0000000..b362fa7 --- /dev/null +++ b/swig/Makefile.am @@ -0,0 +1,15 @@ +EXTRA_DIST = nlopt.i nlopt-guile.i + +BUILT_SOURCES = nlopt-guile.cpp nlopt-renames.i + +HDR = $(top_srcdir)/api/nlopt.hpp + +if MAINTAINER_MODE + +nlopt-guile.cpp: nlopt.i nlopt-enum-renames.i nlopt-guile.i $(top_builddir)/api/nlopt.hpp + swig -I$(top_builddir)/api -outdir $(builddir) -c++ -guile -scmstub -o $@ nlopt.i + +nlopt-enum-renames.i: $(top_srcdir)/api/nlopt.h + (echo "// AUTOMATICALLY GENERATED -- DO NOT EDIT"; egrep 'NLOPT_[LG][DN]|NLOPT_NUM_ALGORITHMS' $(top_srcdir)/api/nlopt.h | sed 's/NLOPT_//g' |tr -d ' ' |tr '/' ',' |tr '=' ',' |cut -d, -f1 |while read name; do echo "%rename(NLOPT_$$name) nlopt::$$name;"; done; egrep 'NLOPT_[A-Z_]* =' $(top_srcdir)/api/nlopt.h | egrep -v 'NLOPT_[LG][DN]' | sed 's/NLOPT_//g' |tr -d ' ' |cut -d'=' -f1 | while read name; do echo "%rename(NLOPT_$$name) nlopt::$$name;"; done) > $@ + +endif diff --git a/swig/nlopt-guile.i b/swig/nlopt-guile.i new file mode 100644 index 0000000..7414b8a --- /dev/null +++ b/swig/nlopt-guile.i @@ -0,0 +1,41 @@ +// -*- C++ -*- + +%{ +static double vfunc_guile(const std::vector &x, + std::vector &grad, void *f) { + SCM xscm = scm_c_make_vector(x.size(), SCM_UNSPECIFIED); + for (unsigned i = 0; i < x.size(); ++i) + scm_c_vector_set_x(xscm, i, scm_make_real(x[i])); + SCM ret = scm_call_2((SCM) f, xscm); + if (scm_real_p(ret)) { + if (grad.size()) throw std::invalid_argument("missing gradient"); + return scm_to_double(ret); + } + else if (scm_is_pair(ret)) { /* must be (cons value gradient) */ + SCM valscm = SCM_CAR(ret), grad_scm = grad_scm; + if (grad.size() > 0 + && scm_is_vector(grad_scm) + && scm_c_vector_length(grad_scm) == grad.size()) { + for (unsigned i = 0; i < grad.size(); ++i) + grad[i] = scm_to_double(scm_c_vector_ref(grad_scm, i)); + } + else throw std::invalid_argument("invalid gradient"); + if (scm_real_p(valscm)) + return scm_to_double(valscm); + } + throw std::invalid_argument("invalid result passed to nlopt"); +} +%} + +%typemap(in)(nlopt::vfunc vf, void *f_data) { + $1 = vfunc_guile; + $2 = (void*) $input; // input is SCM pointer to Scheme function +} + +// export constants as variables, rather than as functions returning the value +%feature("constasvar", "1"); + +%scheme %{ +(dynamic-link "libnlopt.so") +(load-extension "libnlopt-guile.so" "SWIG_init") +%} diff --git a/swig/nlopt.i b/swig/nlopt.i new file mode 100644 index 0000000..01dc679 --- /dev/null +++ b/swig/nlopt.i @@ -0,0 +1,25 @@ +// -*- C++ -*- +%module nlopt +%{ +#include "nlopt.hpp" +%} + +%include "std_vector.i" +namespace std { + %template(nlopt_doublevector) vector; +}; + +%rename(nlopt_opt) nlopt::opt; +%rename(nlopt_roundoff_limited) nlopt::roundoff_limited; +%rename(nlopt_forced_stop) nlopt::forced_stop; +%rename(nlopt_srand) nlopt::srand; +%rename(nlopt_srand_time) nlopt::srand_time; +%rename(nlopt_version) nlopt::version; +%rename(nlopt_algorithm_name) nlopt::algorithm_name; +%include "nlopt-enum-renames.i" + +#ifdef SWIGGUILE +%include "nlopt-guile.i" +#endif + +%include "nlopt.hpp"