|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
#######
#
# E-scripts about Swig.
#
# Note 1: use the eev command (defined in eev.el) and the
# ee alias (in my .zshrc) to execute parts of this file.
# Executing this file as a whole makes no sense.
# An introduction to eev can be found here:
#
# (find-eev-quick-intro)
# http://angg.twu.net/eev-intros/find-eev-quick-intro.html
#
# Note 2: be VERY careful and make sure you understand what
# you're doing.
#
# Note 3: If you use a shell other than zsh things like |&
# and the for loops may not work.
#
# Note 4: I always run as root.
#
# Note 5: some parts are too old and don't work anymore. Some
# never worked.
#
# Note 6: the definitions for the find-xxxfile commands are on my
# .emacs.
#
# Note 7: if you see a strange command check my .zshrc -- it may
# be defined there as a function or an alias.
#
# Note 8: the sections without dates are always older than the
# sections with dates.
#
# This file is at <http://angg.twu.net/e/swig.e>
# or at <http://angg.twu.net/e/swig.e.html>.
# See also <http://angg.twu.net/emacs.html>,
# <http://angg.twu.net/.emacs[.html]>,
# <http://angg.twu.net/.zshrc[.html]>,
# <http://angg.twu.net/escripts.html>,
# and <http://angg.twu.net/>.
#
#######
# «.swig-debian» (to "swig-debian")
# «.swig-upstream» (to "swig-upstream")
# «.swig-lua-compile» (to "swig-lua-compile")
# «.swig-lua-examples» (to "swig-lua-examples")
# «.swig-docs» (to "swig-docs")
# «.single-source» (to "single-source")
# «.making-L-accessible» (to "making-L-accessible")
# «.making-L-accessible-long» (to "making-L-accessible-long")
# «.mla.c» (to "mla.c")
# «.returning-malloced-blocks» (to "returning-malloced-blocks")
# «.C-types-as-strings» (to "C-types-as-strings")
# «.myswiglua» (to "myswiglua")
#####
#
# Swig for Debian (2012)
# 2012mar04
#
#####
# «swig-debian» (to ".swig-debian")
# (find-status "swig")
# (find-vldifile "swig.list")
# (find-udfile "swig/")
# (find-status "swig-doc")
# (find-vldifile "swig-doc.list")
# (find-udfile "swig-doc/")
# (find-status "swig-examples")
# (find-vldifile "swig-examples.list")
# (find-udfile "swig-examples/")
# (find-fline "/usr/share/doc/swig-examples/lua/")
#####
#
# swig from sarge (too old - doesn't support Lua)
# 2006jun22
#
#####
# (find-status "swig")
# (find-vldifile "swig.list")
# (find-udfile "swig/")
#####
#
# swig-1.3.29 (upstream)
# 2006jun22
#
#####
# http://heanet.dl.sourceforge.net/sourceforge/swig/swig-1.3.29.tar.gz
# (code-c-d "swig" "~/usrc/swig-1.3.29/")
# (find-swigfile "")
# (find-swigfile "configure.in" "--with-lua=path")
# (find-zsh "set | grep -a LUA")
# (find-fline "$LUASRC/")
# (find-swigfile "oc")
# (find-swigfile "oc" "checking for lua")
# (find-swigfile "om")
# (find-swigfile "omi")
#*
# «swig-upstream» (to ".swig-upstream")
# «swig-lua-compile» (to ".swig-lua-compile")
# (find-angg ".zshrc" "lua" "SWIGSRC")
rm -Rv ~/usrc/swig-1.3.29/
tar -C ~/usrc/ -xvzf \
$S/http/heanet.dl.sourceforge.net/sourceforge/swig/swig-1.3.29.tar.gz
cd ~/usrc/swig-1.3.29/
# ./configure |& tee oc
./configure \
--with-lua=$LUASRC/bin/lua \
--with-luaincl=$LUASRC/include \
--with-lualib=$LUASRC/lib \
|& tee oc
# make install is semi-dummy, "--prefix=/tmp/ulocal" is not needed
make |& tee om
make |& tee omi
cd ~/usrc/swig-1.3.29/Examples/lua/class/ && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/constants/ && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/functest/ && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/pointer/ && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/simple/ && make |& tee om
cd ~/usrc/swig-1.3.29/Examples/lua/variables/ && make |& tee om
#*
# «swig-lua-examples» (to ".swig-lua-examples")
# (find-swigfile "oc")
# (find-swigfile "om")
# (find-swigfile "omi")
# (find-swigfile "Examples/lua/")
# (find-swigfile "Examples/lua/check.list")
# (find-swigfile "Examples/lua/class/")
# (find-swigfile "Examples/lua/constants/")
# (find-swigfile "Examples/lua/functest/")
# (find-swigfile "Examples/lua/pointer/")
# (find-swigfile "Examples/lua/simple/")
# (find-swigfile "Examples/lua/variables/")
# (find-swigfile "Examples/lua/simple/")
# (find-swigfile "Examples/lua/simple/om")
# (find-swigfile "Examples/lua/simple/runme.lua")
# (find-man "3 dlopen")
cd ~/usrc/swig-1.3.29/Examples/lua/class/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/constants/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/functest/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/pointer/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/simple/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
lua50 runme.lua |& tee o
cd ~/usrc/swig-1.3.29/Examples/lua/variables/
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \
lua50 runme.lua |& tee o
#*
# (find-swigfile "Examples/Makefile" "lua:")
# (find-node "(gcc)Preprocessor Options" "`-isystem DIR'")
# (find-swigfile "")
# (find-swigfile "Doc/")
# (find-swigw3m "Doc/Manual/Lua.html")
# (find-swigw3m "Doc/Manual/Lua.html" "If you specify `module example'")
# (find-swigfile "Examples/lua/")
# (find-fline "/tmp/swiglua/")
# (find-swigsh "find")
# (find-swigfile "preinst-swig")
#####
#
# swig docs
# 2006jun27
#
#####
# «swig-docs» (to ".swig-docs")
# (find-es "swig")
# (find-swigmanualfile "")
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html
#####
#
# A file that is both a .c and a swig interface file (.swg/.i)
# 2006jun27
#
#####
# «single-source» (to ".single-source")
# (find-swigfile "Examples/lua/simple/")
# (find-node "(cpp)Else")
# (find-swigmanualw3m "Preprocessor.html")
# (find-swigmanualw3m "Preprocessor.html" "defined when SWIG is processing")
# (find-swigmanualw3m "Preprocessor.html#Preprocessor_condition_compilation")
# (find-swigmanualw3m "Preprocessor.html" "SWIGLUA")
#*
rm -Rv /tmp/swig/
mkdir /tmp/swig/
cd /tmp/swig/
cat > example.c <<'---'
#ifdef SWIG
%module example
%inline %{
extern int gcd(int x, int y);
extern double Foo;
%}
#else /* Not SWIG */
double Foo = 3.0;
int gcd(int x, int y) {
int g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
#endif /* Not SWIG */
---
cat > runme.lua <<'---'
lib = loadlib('example.so','Example_Init')
assert(lib)()
x = 42
y = 105
g = example.gcd(x,y)
print("The gcd of",x,"and",y,"is",g)
print("Foo = ", example.Foo)
example.Foo = 3.1415926
print("Foo = ", example.Foo)
---
# (find-swigfile "preinst-swig")
# (find-swigfile "Examples/lua/simple/om")
# (find-node "(gcc)Code Gen Options" "`-fpic'")
# (find-node "(gcc)Overall Options" "more than one input file")
~/usrc/swig-1.3.29/preinst-swig -lua example.c
laf
gcc -shared \
-L $HOME/usrc/lua-5.0.2/lib -llua -llualib \
-isystem $HOME/usrc/lua-5.0.2/include \
-g \
-o example.so \
example.c example_wrap.c
lua50 runme.lua
laf
#*
# (find-sh "set | grep -a src/lua")
#####
#
# real-world tests: titanl
# 2006jun29
#
#####
# (find-eevex "lua.e")
# (find-eevex "lua.e" "lua-gdb-1")
# (find-es "swig")
# (find-es "swig" "single-source")
# (find-fline "titanl_wrap.c")
# (find-efunction 'eeb-gdb-start)
#*
cd ~/TITAN/
$SWIGSRC/preinst-swig -lua titanl.c
gcc -L $LUA50SRC/lib -llua -llualib \
-isystem $LUA50SRC/include \
-g -shared -o titanl.so \
titanl.c titanl_wrap.c
# If there are any broken symbols this will report them:
lua50 -e 'print(loadlib("./titanl.so", "Titanl_Init"))'
cat > runme.lua <<'---'
lib = loadlib("./titanl.so", "Titanl_Init")
assert(lib)()
math.sin(0)
print(titanl.parse_prog_get_max_jump("foo :123 :325 :102 bar"))
---
lua50 runme.lua
#*
# (ee-once (eeb-luagdb-start "bin/lua"))
# br loadlib
set args runme.lua
cd ~/TITAN/
br math_sin
run
br parse_prog_get_max_jump
# cont
#*
# (find-angg "LUA/lua50init.lua" "load_PP")
source ~/.lua50/PP.gdb
#####
#
# calling Lua back from a C function (making L accessible)
# This is the short demo, the long demo is below...
# 2006jul14
#
#####
# «making-L-accessible» (to ".making-L-accessible")
# (find-angg "SWIG/demo_luaClua.c")
#*
rm -Rv /tmp/mla/
mkdir /tmp/mla/
cd /tmp/mla/
cat > mla.c <<'---'
#ifdef SWIG
%module C
%typemap(in) lua_State *L "$1 = L;"
%inline %{
extern int foo(char *str, int n, lua_State *L);
%}
#else /* Not SWIG */
#include "lua.h"
#include "lauxlib.h"
void foo(char *str, int n, lua_State *L) {
printf("C.foo: str=\"%s\", n=%d\n", str, n);
lua_pushstring(L, "bar"); /* function name */
lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */
lua_call(L, 0, 0); /* call function with 0 arguments and 0 results */
}
#endif /* Not SWIG */
---
cat > runme.lua <<'---'
assert(loadlib('mla.so','C_Init'))()
bar = function () print("bar: hello!") end
C.foo("abc", 154)
print("bye!")
---
# (find-angg ".zshrc" "lua" "SWIGSRC")
$SWIGSRC/preinst-swig -lua mla.c
gcc -L $LUA50SRC/lib -llua -llualib -isystem $LUA50SRC/include \
-shared -g -o mla.so mla.c mla_wrap.c
lua50 runme.lua
#*
#####
#
# calling Lua back from a C function (making L accessible)
# This is the long demo, there's a shorter one above.
# 2006jul14
#
#####
# «making-L-accessible-long» (to ".making-L-accessible-long")
<edrx> a swig-lua question, maybe a bit hurried... I'm writing a
function in C, called (say) "process_record", that parses
"records" very quickly... I use swig to call this function from
Lua, and that's working fine
<edrx> but parse_record needs to call a function in Lua called
"traced_p" to check if a certain field of the record is
"traced"... the problem: to call Lua back I need the "L" of the
Lua environment that called the C function...
<edrx> reading parserecord_wrap.c, generated by swig...
<Wallbraker> edrx: you could do a typemap for lua_State
<Wallbraker> abit of a hack but hey.
<edrx> makes sense, lemme find out how...
<Wallbraker> %typemap %typemap(in) lua_State
<edrx> thanks :)
<Wallbraker> %{$1 = L; %}
<Wallbraker> now this is not a small hack tho, make shure you have the
lua_State last in the argument
# (find-swigmanualw3m "SWIG.html")
# (find-swigmanualw3m "Typemaps.html")
# (find-swigmanualw3m "Typemaps.html#Typemaps_nn4")
# (find-swigmanualfile "")
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Typemaps.html
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Typemaps.html#Typemaps_mixed_default
# (find-swigfile "")
# (find-swigfile "Lib/lua/")
# (find-swigfile "Lib/lua/lua.swg")
# (find-swigfile "Lib/lua/luarun.swg")
# (find-swigfile "Lib/lua/typemaps.i")
# (find-swigsh "find | grep -i lua")
%typemap %typemap(in) lua_State
%{ $1 = L; %}
# Bad syntax: this thing doesn't work yet
# «mla.c» (to ".mla.c")
# (find-es "lua5" "monitored_p_C")
#*
rm -Rv /tmp/mla/
mkdir /tmp/mla/
cd /tmp/mla/
cat > mla.c <<'---'
#ifdef SWIG
%module C
%typemap(in) lua_State *L "$1 = L;"
%inline %{
extern int foo(char *str, int n, lua_State *L);
%}
#else /* Not SWIG */
/*
* (find-node "(cpp)The preprocessing language" "before and after the `#'")
* (find-lua50file "include/")
* (find-lua50file "include/lua.h" "#define LUA_GLOBALSINDEX")
* (find-luamanual-ff "pushing")
* (find-luamanualw3m+ "pushing")
* (find-luamanualw3m+ "lua-to" "lua_tonumber converts the Lua value")
* (find-luamanualw3m+ "3.14" "lua_call")
* (find-fline "/tmp/mla/")
* (find-fline "/tmp/mla/mla_wrap.c" "_wrap_foo")
* (find-swigfile "")
*/
#include "lua.h"
#include "lauxlib.h"
int foo(char *str, int n, lua_State *L) {
int subfoo_result;
printf("C.foo: depth at the beginning: %d\n", lua_gettop(L));
lua_pushstring(L, "subfoo"); /* function name */
lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */
lua_pushstring(L, str[0] ? str+1 : "empty"); /* 1st argument */
lua_pushnumber(L, n*10); /* 2nd argument */
lua_call(L, 2, 1); /* call function with 2 arguments and 1 result */
/* now convert the returned value to an int and return it (plus 5) */
subfoo_result = lua_tonumber(L, -1); /* index=-1 means top of stack */
lua_pop(L, 1); /* remove results from stack */
printf("C.foo: depth after lua_pop: %d\n", lua_gettop(L));
return subfoo_result + 5;
}
#endif /* Not SWIG */
---
cat > runme.lua <<'---'
assert(loadlib('mla.so','C_Init'))()
PP(C)
subfoo = function (str, n) print("subfoo: received:", str, n); return 40 end
math.sin(0)
print("subfoo should receive and print: \"bcdef\" 99*10")
print(" and it should return: 40+5")
print("main: C.foo returned:", C.foo("abcdef", 99))
---
~/usrc/swig-1.3.29/preinst-swig -lua mla.c
cd /tmp/mla/
gcc -shared \
-L $HOME/usrc/lua-5.0.2/lib -llua -llualib \
-isystem $HOME/usrc/lua-5.0.2/include \
-g \
-o mla.so \
mla.c mla_wrap.c
laf
lua50 runme.lua
#*
cat > runme.lua <<'---'
lib = loadlib("./titanl.so", "Titanl_Init")
assert(lib)()
math.sin(0)
print(titanl.parse_prog_get_max_jump("foo :123 :325 :102 bar"))
---
lua50 runme.lua
#*
# (ee-once (eeb-luagdb-start "bin/lua"))
# br loadlib
set args runme.lua
cd ~/tmp/mla/
br math_sin
run
br foo_wrap
# cont
#*
# (find-sh "set | grep -a src/lua")
laf
# (find-node "(cpp)The preprocessing language" "before and after the `#'")
#####
#
# C functions that return malloc'ed blocks to Lua
# 2006jul20
#
#####
# «returning-malloced-blocks» (to ".returning-malloced-blocks")
# (find-angg "SWIG/demo_retlstring.c")
# (find-swigmanualfile "")
# (find-swigmanualw3m "")
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html#SWIG_nn32
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Lua.html
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Typemaps.html
# (find-swigmanualw3m "SWIG.html" "%inline")
#*
rm -Rv /tmp/malbl/
mkdir /tmp/malbl/
cd /tmp/malbl/
cat > malbl.c <<'---'
typedef struct malloced_block {
void *ptr;
int len;
} malloced_block;
#ifdef SWIG
%module C
%typemap(out) malloced_block %{
lua_pushstring(L, $1.ptr, $1.len);
free($1.ptr);
%}
%inline %{
extern malloced_block foo(void);
%}
#else /* Not SWIG */
#include <stdlib.h>
#include <string.h>
malloced_block foo(void) {
malloced_block mb;
mb.ptr = malloc(7);
mb.len = 7;
strcpy(mb.ptr, "Hello!");
return mb;
}
#endif
---
cat > runme.lua <<'---'
assert(loadlib('malbl.so','C_Init'))()
print(C.foo())
---
$SWIGSRC/preinst-swig -lua malbl.c
gcc -L $LUA50SRC/lib -llua -llualib -isystem $LUA50SRC/include \
-Wall \
-shared -g -o malbl.so malbl.c malbl_wrap.c
lua50 runme.lua
#*
# (find-angg ".zshrc" "lua" "SWIGSRC")
#####
#
# swig's encoding of C types as strings
# 2006jul21
#
#####
# «C-types-as-strings» (to ".C-types-as-strings")
# (find-es "anatocc" "cdecl")
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Extending.html#Extending_nn24
# (find-swigmanualw3m "Extending.html#Extending_nn24")
C datatype SWIG encoding (strings)
----------------------- -------------------------
int "int"
int * "p.int"
const int * "p.q(const).int"
int (*x)(int,double) "p.f(int,double).int"
int [20][30] "a(20).a(30).int"
int (F::*)(int) "m(F).f(int).int"
vector<int> * "p.vector<(int)>"
#####
#
# how %inline works
# 2006jul21
#
#####
file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html
file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/SWIG.html#SWIG_nn43
file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Typemaps.html
<edrx> is it possible to use typemaps to create new "primitive" types,
like int? I just read the section "string encoding of types" in
the "Extending Swig" section of the manual...
<edrx> actually I'm a newcomer to swig - I'm trying to find a way to
have C functions that malloc a region of memory and then return
that region (a pointer + a length) as a Lua string...
<edrx> my idea was to use a typemap and something like
<edrx> %typemap(out) lstring %{ lua_pushlstring(L, $1.ptr, $1.len);
free($1.ptr); %}
<edrx> but to make things cleaner I'd like to tell swig to not look
inside lstrings and do not provide accessor functions
#####
#
# myswiglua
# 2006jul24
#
#####
# «myswiglua» (to ".myswiglua")
# (find-angg ".zshrc" "swig")
# (find-angg "LUA/lua50init.lua" "loadswigso")
# file:///home/edrx/usrc/swig-1.3.29/Doc/Manual/Contents.html
# Local Variables:
# coding: utf-8-unix
# End: