update swig on windows

This commit is contained in:
Bassem Girgis
2019-08-04 21:38:19 -05:00
parent 8414b7136b
commit 76ad52be58
5943 changed files with 91790 additions and 71892 deletions

View File

@@ -0,0 +1,22 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,25 @@
/* File : example.c */
#include <stdlib.h>
/* we are using the qsort function, which needs a helper function to sort */
int compare_int(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
void sort_int(int* arr, int len)
{
qsort(arr, len, sizeof(int), compare_int);
}
/* ditto doubles */
int compare_double(const void * a, const void * b)
{
return (int)( *(double*)a - *(double*)b );
}
void sort_double(double* arr, int len)
{
qsort(arr, len, sizeof(double), compare_double);
}

View File

@@ -0,0 +1,43 @@
/* File : example.i */
%module example
/* in this file there are two sorting functions
and three different ways to wrap them.
See the lua code for how they are called
*/
%include <carrays.i> // array helpers
// this declares a batch of function for manipulating C integer arrays
%array_functions(int,int)
// this adds some lua code directly into the module
// warning: you need the example. prefix if you want it added into the module
// admittedly this code is a bit tedious, but its a one off effort
%luacode {
function example.sort_int2(t)
-- local len=table.maxn(t) -- the len - maxn deprecated in 5.3
local len=0; for _ in pairs(t) do len=len+1 end
local arr=example.new_int(len)
for i=1,len do
example.int_setitem(arr,i-1,t[i]) -- note: C index is one less then lua index
end
example.sort_int(arr,len) -- call the fn
-- copy back
for i=1,len do
t[i]=example.int_getitem(arr,i-1) -- note: C index is one less then lua index
end
example.delete_int(arr) -- must delete it
end
}
// this way uses the SWIG-Lua typemaps to do the conversion for us
// the %apply command states to apply this wherever the argument signature matches
%include <typemaps.i>
%apply (double *INOUT,int) {(double* arr,int len)};
%inline %{
extern void sort_int(int* arr, int len);
extern void sort_double(double* arr, int len);
%}

View File

@@ -0,0 +1,74 @@
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
-- a helper to print a Lua table
function print_table(t)
print(table.concat(t,","))
end
-- a helper to print a C array
function print_array(arr,len)
for i=0,len-1 do
io.write(example.int_getitem(arr,i),",")
end
io.write("\n")
end
math.randomseed(0) -- init random
--[[ version 1: passing a C array to the code
let's test call sort_int()
this requires a C array, so is the hardest to use]]
ARRAY_SIZE=10
arr=example.new_int(ARRAY_SIZE)
for i=0,ARRAY_SIZE-1 do
example.int_setitem(arr,i,math.random(1000))
end
print "unsorted"
print_array(arr,ARRAY_SIZE)
example.sort_int(arr,ARRAY_SIZE)
print "sorted"
print_array(arr,ARRAY_SIZE)
example.delete_int(arr) -- must delete it
print ""
--[[ version 2: using %luacode to write a helper
a simpler way is to use a %luacode
which is a lua function added into the module
this can do the conversion for us
so we can just add a lua table directly
(what we do is move the lua code into the module instead)
]]
t={}
for i=1,ARRAY_SIZE do
t[i]=math.random(1000)
end
print "unsorted"
print_table(t)
example.sort_int2(t) -- calls lua helper which then calls C
print "sorted"
print_table(t)
print ""
--[[ version 3: use a typemap
this is the best way
it uses the SWIG-Lua typemaps to do the work
one item of note: the typemap creates a copy, rather than edit-in-place]]
t={}
for i=1,ARRAY_SIZE do
t[i]=math.random(1000)/10
end
print "unsorted"
print_table(t)
t=example.sort_double(t) -- replace t with the result
print "sorted"
print_table(t)

View File

@@ -0,0 +1,18 @@
# see top-level Makefile.in
arrays
class
constants
dual
embed
embed2
embed3
exception
funcptr3
functest
functor
import
nspace
owner
pointer
simple
variables

View File

@@ -0,0 +1,23 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS = -lm
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,61 @@
-- file: runme.lua
-- This file illustrates class C++ interface generated
-- by SWIG.
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
----- Object creation -----
print("Creating some objects:")
c = example.Circle(10)
print(" Created circle", c)
s = example.Square(10)
print(" Created square", s)
----- Access a static member -----
print("\nA total of",example.Shape_nshapes,"shapes were created")
----- Member data access -----
-- Set the location of the object
c.x = 20
c.y = 30
s.x = -10
s.y = 5
print("\nHere is their current position:")
print(string.format(" Circle = (%f, %f)",c.x,c.y))
print(string.format(" Square = (%f, %f)",s.x,s.y))
----- Call some methods -----
print("\nHere are some properties of the shapes:")
for _,o in pairs({c,s}) do
print(" ", o)
print(" area = ", o:area())
print(" perimeter = ", o:perimeter())
end
print("\nGuess I'll clean up now")
-- Note: this invokes the virtual destructor
c=nil
s=nil
-- call gc to make sure they are collected
collectgarbage()
print(example.Shape_nshapes,"shapes remain")
print "Goodbye"

View File

@@ -0,0 +1,23 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
TARGET = example
INTERFACE = example.i
LIBS =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,27 @@
/* 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 directives also produce constants */
%constant int iconst = 37;
%constant double fconst = 3.14;

View File

@@ -0,0 +1,35 @@
-- file: example.lua
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
print("ICONST = "..example.ICONST.." (should be 42)")
print("FCONST = "..example.FCONST.." (should be 2.1828)")
print("CCONST = "..example.CCONST.." (should be 'x')")
print("CCONST2 = "..example.CCONST2.." (this should be on a new line)")
print("SCONST = "..example.SCONST.." (should be 'Hello World')")
print("SCONST2 = "..example.SCONST2.." (should be '\"Hello World\"')")
print("EXPR = "..example.EXPR.." (should be 48.5484)")
print("iconst = "..example.iconst.." (should be 37)")
print("fconst = "..example.fconst.." (should be 3.14)")
-- helper to check that a fn failed
function checkfail(fn)
if pcall(fn)==true then
print("that shouldn't happen, it worked")
else
print("function failed as expected")
end
end
-- these should fail
-- example.EXTERN is a nil value, so concatentatin will make it fail
checkfail(function() print("EXTERN = "..example.EXTERN) end)
checkfail(function() print("FOO = "..example.FOO) end)

View File

@@ -0,0 +1,27 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
TARGET = dual
GENCXXSRCS = example2_wrap.cxx
INTERFACE = dual.i
LUA_INTERP = dual.cpp
# This is a little different to normal as we need to static link two modules and a custom interpreter
# We need the external runtime, then swig examples2, and build the module as normal
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' lua_embed_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
lua_externalhdr
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='-c++' INTERFACE='example2.i' lua_swig_cpp
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) GENCXXSRCS='$(GENCXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' LUA_INTERP='$(LUA_INTERP)' lua_static_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean
rm -f swigluarun.h $(TARGET)

View File

@@ -0,0 +1,113 @@
/*
dual.cpp a test for multiple modules and multiple interpreters statically linked together.
Earlier version of lua bindings for SWIG would fail if statically linked.
What is happening is as follows:
example.i declares a type Foo
examples2.i declares Bar
The first lua state will load example.i
and check to see if types Foo and Bar are registered with it
(Foo should be & Bar should not)
The second lua state will load example2.i
and check to see if types Foo and Bar are registered with it
(Bar should be & Foo should not)
Note: Though both the modules exist and are loaded, they are not linked together,
as they are connected to separate lua interpreters.
When the third lua state loads both example.i and example2.i,
the two modules are now linked together, and all can now find
both Foo and Bar.
*/
#include "swigluarun.h" // the swig runtimes
#include <stdio.h>
#include <stdlib.h>
// the 2 libraries which are wrapped via SWIG
extern "C" int luaopen_example(lua_State*L);
extern "C" int luaopen_example2(lua_State*L);
#define DEBUG(X) {printf(X);fflush(stdout);}
#define DEBUG2(X,Y) {printf(X,Y);fflush(stdout);}
#define DEBUG3(X,Y,Z) {printf(X,Y,Z);fflush(stdout);}
#if LUA_VERSION_NUM > 501
#define lua_open luaL_newstate
#endif
void testModule(lua_State *L)
{
swig_type_info *pTypeInfo=0,*pTypeInfo2=0;
swig_module_info *pModule=0;
pModule=SWIG_GetModule(L);
DEBUG2(" SWIG_GetModule() returns %p\n", (void *)pModule)
if(pModule==0) return;
pTypeInfo = SWIG_TypeQuery(L,"Foo *");
DEBUG2(" Type (Foo*) is %s\n",pTypeInfo==0?"unknown":"known");
DEBUG3(" Module %p typeinfo(Foo*) %p\n", (void *)pModule, (void *)pTypeInfo);
pTypeInfo2 = SWIG_TypeQuery(L,"Bar *");
DEBUG2(" Type (Bar*) is %s\n",pTypeInfo2==0?"unknown":"known");
DEBUG3(" Module %p typeinfo(Bar*) %p\n", (void *)pModule, (void *)pTypeInfo2);
}
int main(int argc,char* argv[])
{
lua_State *L1=0,*L2=0,*L3=0;
printf("This is a test of having two SWIG'ed modules and three lua states\n"
"statically linked together.\n"
"Its mainly to check that all the types are correctly managed\n\n");
DEBUG("creating lua states(L1,L2,L3)");
L1=lua_open();
L2=lua_open();
L3=lua_open();
DEBUG("ok\n\n");
DEBUG("luaopen_example(L1)..");
luaopen_example(L1);
DEBUG("ok\n");
DEBUG("Testing Module L1\n");
DEBUG("This module should know about Foo* but not Bar*\n");
testModule(L1);
DEBUG("End Testing Module L1\n\n");
DEBUG("luaopen_example2(L2)..");
luaopen_example2(L2);
DEBUG("ok\n");
DEBUG("Testing Module L2\n");
DEBUG("This module should know about Bar* but not Foo*\n");
testModule(L2);
DEBUG("End Testing Module L2\n\n");
DEBUG("luaopen_example(L3)..");
luaopen_example(L3);
DEBUG("ok\n");
DEBUG("luaopen_example2(L3)..");
luaopen_example2(L3);
DEBUG("ok\n");
DEBUG("Testing Module L3\n");
DEBUG("This module should know about Foo* and Bar*\n");
testModule(L3);
DEBUG("End Testing Module L3\n\n");
DEBUG("Testing Module L1 again\n");
DEBUG("It now should know about Foo* and Bar*\n");
testModule(L1);
DEBUG("End Testing Module L1 again\n\n");
DEBUG("close all..");
lua_close(L1);
lua_close(L2);
lua_close(L3);
DEBUG("ok, exiting\n");
return 0;
}

View File

@@ -0,0 +1,10 @@
/* File : example.i */
%module example
%inline %{
struct Foo{
int i;
};
%}

View File

@@ -0,0 +1,10 @@
/* File : example2.i */
%module example2
%inline %{
struct Bar{
int i;
};
%}

View File

@@ -0,0 +1,22 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
TARGET = embed
SRCS = example.c
INTERFACE = example.i
LUA_INTERP = embed.c
LIBS = -lm
# this is a little different to normal as we have our own special interpreter
# which we want to static link
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' lua_embed_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' LIBS='$(LIBS)' INTERFACE='example.i' LUA_INTERP='$(LUA_INTERP)' lua_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean
rm -f $(TARGET)

View File

@@ -0,0 +1,94 @@
/* embed.c a simple test for an embedded interpreter
The idea is that we wrapper a few simple function (example.c)
and write our own app to call it.
What it will do is load the wrapped lib, load runme.lua and then call some functions.
To make life easier, all the printf's have either [C] or [Lua] at the start
so you can see where they are coming from.
We will be using the luaL_dostring()/lua_dostring() function to call into lua
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#if LUA_VERSION_NUM > 501
#define lua_open luaL_newstate
#endif
/* the SWIG wrappered library */
extern int luaopen_example(lua_State*L);
/* a really simple way of calling lua from C
just give it a lua state & a string to execute
Unfortunately lua keeps changing its API's.
In lua 5.0.X it's lua_dostring()
In lua 5.1.X it's luaL_dostring()
so we have a few extra compiles
*/
int dostring(lua_State *L, char* str) {
int ok;
#if (defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM>=501))
ok=luaL_dostring(L,str); /* looks like this is lua 5.1.X or later, good */
#else
ok=lua_dostring(L,str); /* might be lua 5.0.x, using lua_dostring */
#endif
if (ok!=0)
printf("[C] ERROR in dostring: %s\n",lua_tostring(L,-1));
return ok;
}
int main(int argc,char* argv[]) {
lua_State *L;
int ok;
printf("[C] Welcome to the simple embedded lua example\n");
printf("[C] We are in C\n");
printf("[C] opening a lua state & loading the libraries\n");
L=lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C] now loading the SWIG wrapped library\n");
luaopen_example(L);
printf("[C] all looks ok\n");
printf("\n");
if (argc != 2 || argv[1] == NULL || strlen(argv[1]) == 0) {
printf("[C] ERROR: no lua file given on command line\n");
exit(3);
}
printf("[C] let's load the file '%s'\n", argv[1]);
printf("[C] any lua code in this file will be executed\n");
if (luaL_loadfile(L, argv[1]) || lua_pcall(L, 0, 0, 0)) {
printf("[C] ERROR: cannot run lua file: %s",lua_tostring(L, -1));
exit(3);
}
printf("[C] We are now back in C, all looks ok\n");
printf("\n");
printf("[C] let's call the function 'do_tests()'\n");
ok=dostring(L,"do_tests()");
printf("[C] We are back in C, the dostring() function returned %d\n",ok);
printf("\n");
printf("[C] Let's call lua again, but create an error\n");
ok=dostring(L,"no_such_function()");
printf("[C] We are back in C, the dostring() function returned %d\n",ok);
printf("[C] it should also have returned 1 and printed an error message\n");
printf("\n");
printf("[C] Let's call lua again, calling the greeting function\n");
ok=dostring(L,"call_greeting()");
printf("[C] This was C=>Lua=>C (getting a bit complex)\n");
printf("\n");
printf("[C] all finished, closing the lua state\n");
lua_close(L);
return 0;
}

View File

@@ -0,0 +1,22 @@
/* File : example.c */
#include <stdio.h>
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
void greeting() {
printf("Hello from the C function 'greeting'\n");
}

View File

@@ -0,0 +1,8 @@
/* File : example.i */
%module example
%inline %{
extern int gcd(int x, int y);
extern double Foo;
extern void greeting();
%}

View File

@@ -0,0 +1,40 @@
print "[lua] This is runme.lua"
-- test program for embedded lua
-- we do not need to load the library, as it was already in the interpreter
-- but let's check anyway
assert(type(example)=='table',"Don't appear to have loaded the example module")
-- a test function to run the tests
function do_tests()
print("[lua] We are now in Lua, inside the do_tests() function")
print("[lua] We will be calling example.gcd() and changing example.Foo")
-- Call our gcd() function
x = 42
y = 105
g = example.gcd(x,y)
print("[lua] The gcd of",x,"and",y,"is",g)
-- Manipulate the Foo global variable
-- Output its current value
print("[lua] Foo = ", example.Foo)
-- Change its value
example.Foo = 3.1415926
-- See if the change took effect
print("[lua] Foo = ", example.Foo)
print("[lua] ending the do_tests() function")
end
function call_greeting()
print("[lua] We are now in Lua, inside the call_greeting() function")
example.greeting()
print("[lua] ending the call_greeting() function")
end

View File

@@ -0,0 +1,22 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
TARGET = embed2
SRCS = example.c
INTERFACE = example.i
LUA_INTERP = embed2.c
LIBS = -lm
# this is a little different to normal as we have our own special interpreter
# which we want to static link
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' lua_embed_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' $(SWIGLIB) SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' LIBS='$(LIBS)' INTERFACE='example.i' LUA_INTERP='$(LUA_INTERP)' lua_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean
rm -f $(TARGET)

View File

@@ -0,0 +1,240 @@
/* embed2.c some more tests for an embedded interpreter
This will go a bit further as it will pass values to and from the lua code.
It uses less of the SWIG code, and more of the raw lua API's
What it will do is load the wrapped lib, load runme.lua and then call some functions.
To make life easier, all the printf's have either [C] or [Lua] at the start
so you can see where they are coming from.
We will be using the luaL_dostring()/lua_dostring() function to call into lua
*/
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE
#endif
/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
# define _SCL_SECURE_NO_DEPRECATE
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdarg.h>
#include <string.h>
#if LUA_VERSION_NUM > 501
#define lua_open luaL_newstate
#endif
/* the SWIG wrapped library */
extern int luaopen_example(lua_State*L);
/* This is an example of how to call the Lua function
int add(int,int)
its very tedious, but gives you an idea of the issues involved.
(look below for a better idea)
*/
int call_add(lua_State *L,int a,int b,int* res) {
int top;
/* ok, here we go:
push a, push b, call 'add' check & return res
*/
top=lua_gettop(L); /* for later */
lua_getglobal(L, "add"); /* function to be called */
if (!lua_isfunction(L,-1)) {
printf("[C] error: cannot find function 'add'\n");
lua_settop(L,top);
return 0;
}
lua_pushnumber(L,a);
lua_pushnumber(L,b);
if (lua_pcall(L, 2, 1, 0) != 0) /* call function with 2 arguments and 1 result */
{
printf("[C] error running function `add': %s\n",lua_tostring(L, -1));
lua_settop(L,top);
return 0;
}
/* check results */
if (!lua_isnumber(L,-1)) {
printf("[C] error: returned value is not a number\n");
lua_settop(L,top);
return 0;
}
*res=(int)lua_tonumber(L,-1);
lua_settop(L,top); /* reset stack */
return 1;
}
/* This is a variargs call function for calling from C into Lua.
Original Code from Programming in Lua (PIL) by Roberto Ierusalimschy
ISBN 85-903798-1-7
http://www.lua.org/pil/25.3.html
This has been modified slightly to make it compile, and it's still a bit rough.
But it gives the idea of how to make it work.
*/
int call_va (lua_State *L,const char *func, const char *sig, ...) {
va_list vl;
int narg, nres; /* number of arguments and results */
int top;
top=lua_gettop(L); /* for later */
va_start(vl, sig);
lua_getglobal(L, func); /* get function */
/* push arguments */
narg = 0;
while (*sig) { /* push arguments */
switch (*sig++) {
case 'd': /* double argument */
lua_pushnumber(L, va_arg(vl, double));
break;
case 'i': /* int argument */
lua_pushnumber(L, va_arg(vl, int));
break;
case 's': /* string argument */
lua_pushstring(L, va_arg(vl, char *));
break;
case '>':
goto endwhile;
default:
printf("invalid option (%c)\n", *(sig - 1));
goto fail;
}
narg++;
/* do we need this?*/
/* luaL_checkstack(L, 1, "too many arguments"); */
}
endwhile:
/* do the call */
nres = (int)strlen(sig); /* number of expected results */
if (lua_pcall(L, narg, nres, 0) != 0) /* do the call */
{
printf("error running function `%s': %s\n",func, lua_tostring(L, -1));
goto fail;
}
/* retrieve results */
nres = -nres; /* stack index of first result */
while (*sig) { /* get results */
switch (*sig++) {
case 'd': /* double result */
if (!lua_isnumber(L, nres)) {
printf("wrong result type\n");
goto fail;
}
*va_arg(vl, double *) = lua_tonumber(L, nres);
break;
case 'i': /* int result */
if (!lua_isnumber(L, nres)) {
printf("wrong result type\n");
goto fail;
}
*va_arg(vl, int *) = (int)lua_tonumber(L, nres);
break;
case 's': /* string result */
if (!lua_isstring(L, nres)) {
printf("wrong result type\n");
goto fail;
}
strcpy(va_arg(vl, char *),lua_tostring(L, nres));/* WARNING possible buffer overflow */
break;
default: {
printf("invalid option (%c)", *(sig - 1));
goto fail;
}
}
nres++;
}
va_end(vl);
lua_settop(L,top); /* reset stack */
return 1; /* ok */
fail:
lua_settop(L,top); /* reset stack */
return 0; /* error */
}
int main(int argc,char* argv[]) {
lua_State *L;
int ok;
int res;
char str[80];
printf("[C] Welcome to the simple embedded Lua example v2\n");
printf("[C] We are in C\n");
printf("[C] opening a Lua state & loading the libraries\n");
L=lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C] now loading the SWIG wrappered library\n");
luaopen_example(L);
printf("[C] all looks ok\n");
printf("\n");
if (argc != 2 || argv[1] == NULL || strlen(argv[1]) == 0) {
printf("[C] ERROR: no lua file given on command line\n");
exit(3);
}
printf("[C] let's load the file '%s'\n", argv[1]);
printf("[C] any lua code in this file will be executed\n");
if (luaL_loadfile(L, argv[1]) || lua_pcall(L, 0, 0, 0)) {
printf("[C] ERROR: cannot run lua file: %s",lua_tostring(L, -1));
exit(3);
}
printf("[C] We are now back in C, all looks ok\n");
printf("\n");
printf("[C] let's call the Lua function 'add(1,1)'\n");
printf("[C] using the C function 'call_add'\n");
ok=call_add(L,1,1,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] let's do this rather easier\n");
printf("[C] we will call the same Lua function using a generic C function 'call_va'\n");
ok=call_va(L,"add","ii>i",1,1,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] we will now use the same generic C function to call 'append(\"cat\",\"dog\")'\n");
ok=call_va(L,"append","ss>s","cat","dog",str);
printf("[C] the function returned %d with value %s\n",ok,str);
printf("\n");
printf("[C] we can also make some bad calls to ensure the code doesn't fail\n");
printf("[C] calling adds(1,2)\n");
ok=call_va(L,"adds","ii>i",1,2,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("[C] calling add(1,'fred')\n");
ok=call_va(L,"add","is>i",1,"fred",&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] Note: no protection if you mess up the va-args, this is C\n");
printf("\n");
printf("[C] Finally we will call the wrappered gcd function gdc(6,9):\n");
printf("[C] This will pass the values to Lua, then call the wrappered function\n");
printf(" Which will get the values from Lua, call the C code \n");
printf(" and return the value to Lua and eventually back to C\n");
printf("[C] Certainly not the best way to do it :-)\n");
ok=call_va(L,"gcd","ii>i",6,9,&res);
printf("[C] the function returned %d with value %d\n",ok,res);
printf("\n");
printf("[C] all finished, closing the lua state\n");
lua_close(L);
return 0;
}

View File

@@ -0,0 +1,22 @@
/* File : example.c */
#include <stdio.h>
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}
void greeting() {
printf("Hello from the C function 'greeting'\n");
}

View File

@@ -0,0 +1,8 @@
/* File : example.i */
%module example
%inline %{
extern int gcd(int x, int y);
extern double Foo;
extern void greeting();
%}

View File

@@ -0,0 +1,27 @@
print "[lua] This is runme.lua"
-- test program for embedded lua
-- we do not need to load the library, as it was already in the interpreter
-- but let's check anyway
assert(type(example)=='table',"Don't appear to have loaded the example module")
-- note: we will copy the functions from example table into global
-- this will help us later
for k,v in pairs(example) do _G[k]=v end
-- our add function
-- we will be calling this from C
function add(a,b)
print("[lua] this is function add(",a,b,")")
c=a+b
print("[lua] returning",c)
return c
end
function append(a,b)
print("[lua] this is function append(",a,b,")")
c=a..b
print("[lua] returning",c)
return c
end

View File

@@ -0,0 +1,25 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
TARGET = embed3
SRCS = example.cpp
INTERFACE = example.i
LUA_INTERP = embed3.cpp
# this is a little different to normal as we have our own special interpreter
# which we want to static link
# we also need the external runtime, so we can get access to certain internals of SWIG
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' lua_embed_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
lua_externalhdr
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' LUA_INTERP='$(LUA_INTERP)' lua_static_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean
rm -f swigluarun.h $(TARGET)

View File

@@ -0,0 +1,153 @@
/* embed3.cpp A C++ embedded interpreter
This will register a C++ class with Lua, and then call a Lua function
passing C++ objects to this function.
*/
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
# define _CRT_SECURE_NO_DEPRECATE
#endif
/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
# define _SCL_SECURE_NO_DEPRECATE
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#if LUA_VERSION_NUM > 501
#define lua_open luaL_newstate
#endif
/* The SWIG external runtime is generated by using.
swig -lua -externalruntime swigluarun.h
It contains useful function used by SWIG in its wrapper
SWIG_TypeQuery() SWIG_NewPointerObj()
*/
#include "swigluarun.h" // the SWIG external runtime
/* the SWIG wrapped library */
extern "C" int luaopen_example(lua_State*L);
// the code itself
#include "example.h"
// this code pushes a C++ pointer as well as the SWIG type onto the Lua stack
bool push_pointer(lua_State*L, void* ptr, const char* type_name, int owned = 0) {
// task 1: get the object 'type' which is registered with SWIG
// you need to call SWIG_TypeQuery() with the class name
// (normally, just look in the wrapper file to get this)
swig_type_info * pTypeInfo = SWIG_TypeQuery(L, type_name);
if (pTypeInfo == 0)
return false; // error
// task 2: push the pointer to the Lua stack
// this requires a pointer & the type
// the last param specifies if Lua is responsible for deleting the object
SWIG_NewPointerObj(L, ptr, pTypeInfo, owned);
return true;
}
/* This is an example of how to call the Lua function
void onEvent(Event e)
its very tedious, but gives you an idea of the issues involed.
*/
int call_onEvent(lua_State *L, Event e) {
int top;
/* ok, here we go:
push a, push b, call 'add' check & return res
*/
top = lua_gettop(L); /* for later */
lua_getglobal(L, "onEvent"); /* function to be called */
if (!lua_isfunction(L, -1)) {
printf("[C++] error: cannot find function 'OnEvent'\n");
lua_settop(L, top); // reset
return 0;
}
// push the event object
push_pointer(L, &e, "Event *", 0);
if (lua_pcall(L, 1, 0, 0) != 0) /* call function with 1 arguments and no result */
{
printf("[C++] error running function `OnEvent': %s\n", lua_tostring(L, -1));
lua_settop(L, top); // reset
return 0;
}
lua_settop(L, top); /* reset stack */
return 1; // ok
}
int main(int argc, char* argv[]) {
printf("[C++] Welcome to the simple embedded Lua example v3\n");
printf("[C++] We are in C++\n");
printf("[C++] opening a Lua state & loading the libraries\n");
lua_State *L = lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C++] now loading the SWIG wrappered library\n");
luaopen_example(L);
printf("[C++] all looks ok\n");
printf("\n");
printf("[C++] let's create an Engine and pass a pointer to Lua\n");
Engine engine;
/* this code will pass a pointer into lua, but C++ still owns the object
this is a little tedious, to do, but let's do it
we need to pass the pointer (obviously), the type name
and a flag which states if Lua should delete the pointer once its finished with it
The type name is a class name string which is registered with SWIG
(normally, just look in the wrapper file to get this)
in this case we don't want Lua to delete the pointer so the ownership flag is 0
*/
push_pointer(L,&engine,"Engine *",0);
lua_setglobal(L, "pEngine"); // set as global variable
if (argc != 2 || argv[1] == NULL || strlen(argv[1]) == 0) {
printf("[C++] ERROR: no lua file given on command line\n");
exit(3);
}
printf("[C++] now let's load the file '%s'\n", argv[1]);
printf("[C++] any lua code in this file will be executed\n");
if (luaL_loadfile(L, argv[1]) || lua_pcall(L, 0, 0, 0)) {
printf("[C++] ERROR: cannot run lua file: %s",lua_tostring(L, -1));
exit(3);
}
printf("[C++] We are now back in C++, all looks ok\n");
printf("\n");
printf("[C++] Let's call the Lua function onEvent(e)\n");
printf("[C++] We will give it different events, as we wish\n");
printf("[C++] Starting with STARTUP\n");
Event ev;
ev.mType = Event::STARTUP;
call_onEvent(L, ev);
printf("[C++] ok\n");
printf("[C++] now we will try MOUSEPRESS,KEYPRESS,MOUSEPRESS\n");
ev.mType = Event::MOUSEPRESS;
call_onEvent(L, ev);
ev.mType = Event::KEYPRESS;
call_onEvent(L, ev);
ev.mType = Event::MOUSEPRESS;
call_onEvent(L, ev);
printf("[C++] ok\n");
printf("[C++] Finally we will SHUTDOWN\n");
ev.mType = Event::SHUTDOWN;
call_onEvent(L, ev);
printf("[C++] ok\n");
printf("\n");
printf("[C++] all finished, closing the lua state\n");
lua_close(L);
return 0;
}

View File

@@ -0,0 +1,25 @@
/* File : example.cpp */
#include <stdio.h>
#include "example.h"
void Engine::start()
{
printf("[C++] Engine::start()\n");
}
void Engine::stop()
{
printf("[C++] Engine::stop()\n");
}
void Engine::accelerate(float f)
{
printf("[C++] Engine::accelerate(%f)\n",f);
}
void Engine::decelerate(float f)
{
printf("[C++] Engine::decelerate(%f)\n",f);
}

View File

@@ -0,0 +1,24 @@
/* File : example.h */
/* This is some kind of engine of some kind
we will give it some dummy methods for Lua to call*/
class Engine
{
public:
void start();
void stop();
void accelerate(float f);
void decelerate(float f);
};
/* We also want to pass some events to Lua, so let's have a few classes
to do this.
*/
class Event
{
public:
enum {STARTUP,KEYPRESS,MOUSEPRESS,SHUTDOWN} mType;
// etc
};

View File

@@ -0,0 +1,8 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
%include "example.h"

View File

@@ -0,0 +1,35 @@
print "[lua] This is runme.lua"
-- test program for embedded lua
-- we do not need to load the library, as it was already in the interpreter
-- but let's check anyway
assert(type(example)=='table',"Don't appear to have loaded the example module. Do not run this file directly, run the embed3 executable")
print "[lua] looking to see if we have a pointer to the engine"
if type(pEngine)=="userdata" then
print "[lua] looks good"
else
print "[lua] nope, no signs of it"
end
-- the embedded program expects a function void onEvent(Event)
-- this is it
function onEvent(e)
print("[Lua] onEvent with event",e.mType)
-- let's do something with the Engine
-- nothing clever, but ...
if e.mType==example.Event_STARTUP then
pEngine:start()
elseif e.mType==example.Event_KEYPRESS then
pEngine:accelerate(0.4)
elseif e.mType==example.Event_MOUSEPRESS then
pEngine:decelerate(0.4)
elseif e.mType==example.Event_SHUTDOWN then
pEngine:stop()
else
error("unknown event type")
end
print("[Lua] ending onEvent")
end

View File

@@ -0,0 +1,23 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
TARGET = example
INTERFACE = example.i
LIBS = -lm
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,45 @@
/* File : example.h */
#include <string.h>
#ifndef SWIG
struct A {
};
#endif
class Exc {
public:
Exc(int c, const char *m) {
code = c;
strncpy(msg,m,256);
}
int code;
char msg[256];
};
class Test {
public:
int simple() {
throw(37);
return 1;
}
int message() {
throw("I died.");
return 1;
}
int hosed() {
throw(Exc(42,"Hosed"));
return 1;
}
int unknown() {
static A a;
throw &a;
return 1;
}
int multi(int x) {
if (x == 1) throw(37);
if (x == 2) throw("Bleah!");
if (x == 3) throw(Exc(42,"No-go-diggy-die"));
return 1;
}
};

View File

@@ -0,0 +1,23 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
%include "std_string.i"
// we want to return Exc objects to the interpreter
// therefore we add this typemap
// note: only works if Exc is copyable
%apply SWIGTYPE EXCEPTION_BY_VAL {Exc};
%catches(int) Test::simple();
%catches(const char *) Test::message();
%catches(Exc) Test::hosed();
%catches(A*) Test::unknown();
%catches(int, const char *, Exc) Test::multi(int x);
/* Let's just grab the original header file here */
%include "example.h"

View File

@@ -0,0 +1,96 @@
-- file: example.lua
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
-- throw a lot of exceptions:
-- you must catch exceptions using pcall and then checking the result
t = example.Test()
print "calling t:unknown()"
ok,res=pcall(function() t:unknown() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "calling t:simple()"
ok,res=pcall(function() t:simple() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "calling t:message()"
ok,res=pcall(function() t:message() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "calling t:hosed()"
ok,res=pcall(function() t:hosed() end)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res.code,res.msg)
end
-- this is a rather strange way to perform the multiple catch of exceptions
print "calling t:multi()"
for i=1,3 do
ok,res=pcall(function() t:multi(i) end)
if ok then
print " that worked! Funny"
else
if swig_type(res)=="Exc *" then
print(" call failed with Exc exception:",res.code,res.msg)
else
print(" call failed with error:",res)
end
end
end
-- this is a bit crazy, but it shows obtaining of the stacktrace
function a()
b()
end
function b()
t:message()
end
print [[
Now let's call function a()
which calls b()
which calls into C++
which will throw an exception!]]
ok,res=pcall(a)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "Now let's do the same using xpcall(a,debug.traceback)"
ok,res=xpcall(a,debug.traceback)
if ok then
print " that worked! Funny"
else
print(" call failed with error:",res)
end
print "As you can see, the xpcall gives a nice stacktrace to work with"
ok,res=pcall(a)
print(ok,res)
ok,res=xpcall(a,debug.traceback)
print(ok,res)

View File

@@ -0,0 +1,23 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,19 @@
/* File : example.c */
int do_op(int a, int b, int (*op)(int,int)) {
return (*op)(a,b);
}
int add(int a, int b) {
return a+b;
}
int sub(int a, int b) {
return a-b;
}
int mul(int a, int b) {
return a*b;
}
int (*funcvar)(int,int) = add;

View File

@@ -0,0 +1,9 @@
/* file: example.h */
extern int do_op(int,int, int (*op)(int,int));
extern int add(int,int);
extern int sub(int,int);
extern int mul(int,int);
extern int (*funcvar)(int,int);

View File

@@ -0,0 +1,69 @@
/* File : example.i */
/*
This demonstrates how to pass a lua function, into some C code and then call it.
There are two examples, the first is as a parameter, the second as a global variable.
*/
%module example
%{
#include "example.h"
%}
/* the extra wrappers for lua functions, see SWIG/Lib/lua/lua_fnptr.i for more details */
%include "lua_fnptr.i"
/* these are a bunch of C functions which we want to be able to call from lua */
extern int add(int,int);
extern int sub(int,int);
extern int mul(int,int);
/* this function takes a lua function as a parameter and calls it.
As this is takes a lua fn it needs lua code
*/
%inline %{
int callback(int a, int b, SWIGLUA_FN fn)
{
SWIGLUA_FN_GET(fn);
lua_pushnumber(fn.L,a);
lua_pushnumber(fn.L,b);
lua_call(fn.L,2,1); /* 2 in, 1 out */
return (int)luaL_checknumber(fn.L,-1);
}
%}
/******************
Second code uses a stored reference.
*******************/
%inline %{
/* note: this is not so good to just have it as a raw ref
people could set anything to this
a better solution would to be to have a fn which wants a SWIGLUA_FN, then
checks the type & converts to a SWIGLUA_REF.
*/
SWIGLUA_REF the_func={0,0};
void call_the_func(int a)
{
int i;
if (the_func.L==0){
printf("the_func is zero\n");
return;
}
swiglua_ref_get(&the_func);
if (!lua_isfunction(the_func.L,-1))
{
printf("the_func is not a function\n");
return;
}
lua_pop(the_func.L,1); /* tidy stack */
for(i=0;i<a;i++)
{
swiglua_ref_get(&the_func);
lua_pushnumber(the_func.L,i);
lua_call(the_func.L,1,0); /* 1 in, 0 out */
}
}
%}

View File

@@ -0,0 +1,54 @@
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
a = 37
b = 42
-- Now call our C function
print("Trying some C functions")
print(" a =", a)
print(" b =", b)
print(" add(a,b) =", example.add(a,b))
print(" sub(a,b) =", example.sub(a,b))
print(" mul(a,b) =", example.mul(a,b))
print("Calling them using the my_func()")
print(" add(a,b) =", example.callback(a,b,example.add))
print(" sub(a,b) =", example.callback(a,b,example.sub))
print(" mul(a,b) =", example.callback(a,b,example.mul))
print("Now let us write our own function")
function foo(a,b) return 101 end
print(" foo(a,b) =", example.callback(a,b,foo))
print("Now let us try something that will fail")
local ok,c=pcall(example.callback,a,b,print)
if ok==false then
print("this failed as expected, error:",c)
else
print("oops, that worked! result:",c)
end
-- part2 stored function
print("trying a stored fn")
print("the_func=",example.the_func)
print("setting to print")
example.the_func=print
print("the_func=",example.the_func)
print("call_the_func(5)")
example.call_the_func(5)
function bar(i) print("bar",i) end
print("setting to bar")
example.the_func=bar
print("call_the_func(5)")
example.call_the_func(5)

View File

@@ -0,0 +1,23 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,25 @@
/* File : example.c */
/* A global variable */
double Foo = 3.0;
int add1(int x, int y)
{
return x+y;
}
void add2(int x, int *y, int *z)
{
*z = x+*y;
}
int add3(int x, int y, int *z)
{
*z = x-y;
return x+y;
}
void add4(int x, int *y)
{
*y += x;
}

View File

@@ -0,0 +1,12 @@
/* File : example.i */
%module example
%include "typemaps.i"
%inline %{
extern int add1(int x, int y); /* return x+y -- basic function test */
extern void add2(int x, int *INPUT, int *OUTPUT); /* *z = x+*y -- argin and argout test */
extern int add3(int x, int y, int *OUTPUT); /* return x+y, *z=x-y -- returning 2 values */
extern void add4(int x, int *INOUT); /* *y += x -- INOUT dual purpose variable */
%}

View File

@@ -0,0 +1,20 @@
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
x,y = 42,105
print("add1 - simple arg passing and single return value -- ")
print(example.add1(x,y))
print("add2 - pointer arg passing and single return value through pointer arg -- ")
print(example.add2(x,y))
print("add3 - simple arg passing and double return value through return and ptr arg -- ")
print(example.add3(x,y))
print("add4 - dual use arg and return value -- ")
print(example.add4(x,y))

View File

@@ -0,0 +1,24 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
TARGET = example
INTERFACE = example.i
LIBS = -lm
SWIGOPT =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,29 @@
/* File : example.i */
%module example
%inline %{
// From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514
template<class T> class Sum {
T res;
public:
Sum(T i = 0) : res(i) { }
void operator() (T x) { res += x; }
T result() const { return res; }
};
%}
// Rename the application operator to __call.
// Note: this is normally automatic, but if you had to do it yourself
// you would use this directive:
//
// %rename(__call) *::operator(); // the fn call operator
// Instantiate a few versions
%template(intSum) Sum<int>;
%template(doubleSum) Sum<double>;

View File

@@ -0,0 +1,24 @@
-- Operator overloading example
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
a = example.intSum(0)
b = example.doubleSum(100.0)
-- Use the objects. They should be callable just like a normal
-- lua function.
for i=0,100 do
a(i) -- Note: function call
b(math.sqrt(i)) -- Note: function call
end
print("int sum 0..100 is",a:result(),"(expected 5050)")
print("double sum 0..100 is",b:result(),"(expected ~771.46)")

View File

@@ -0,0 +1,42 @@
-- import
-- the lua 5.0 loading mechanism is rather poor & relies upon the loadlib() fn
-- the lua 5.1 loading mechanism is simplicity itself
-- for now we need a bridge which will use the correct version
function import_5_0(module)
-- imports the file into the program
-- for a module 'example'
-- this must load 'example.dll' or 'example.so'
-- and look for the fn 'Example_Init()' (note the capitalisation)
if rawget(_G,module)~=nil then return end -- module appears to be loaded
-- capitalising the first letter
local c=string.upper(string.sub(module,1,1))
local fnname=c..string.sub(module,2).."_Init"
local suffix,lib
-- note: as there seems to be no way in lua to determine the platform
-- we will try loading all possible names
-- providing one works, we can load
for _,suffix in pairs{".dll",".so"} do
lib=loadlib(module..suffix,fnname)
if lib then -- found
break
end
end
assert(lib,"error loading module:"..module)
lib() -- execute the function: initialising the lib
local m=rawget(_G,module) -- gets the module object
assert(m~=nil,"no module table found")
end
function import_5_1(module)
require(module)
end
if string.sub(_VERSION,1,7)=='Lua 5.0' then
import=import_5_0
else
import=import_5_1
end

View File

@@ -0,0 +1,25 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SWIGOPT =
LIBS =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='base' INTERFACE='base.i' lua_cpp
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' lua_cpp
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='bar' INTERFACE='bar.i' lua_cpp
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
SWIGOPT='$(SWIGOPT)' LIBS='$(LIBS)' TARGET='spam' INTERFACE='spam.i' lua_cpp
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,36 @@
This example tests the %import directive and working with multiple modules.
Use 'lua runme.lua' to run a test.
Overview:
---------
The example defines 4 different extension modules--each wrapping
a separate C++ class.
base.i - Base class
foo.i - Foo class derived from Base
bar.i - Bar class derived from Base
spam.i - Spam class derived from Bar
Each module uses %import to refer to another module. For
example, the 'foo.i' module uses '%import base.i' to get
definitions for its base class.
If everything is okay, all of the modules will load properly and
type checking will work correctly. Caveat: Some compilers, for example
gcc-3.2.x, generate broken vtables with the inline methods in this test.
This is not a SWIG problem and can usually be solved with non-inlined
destructors compiled into separate shared objects/DLLs.
Unix:
-----
- Run make
- Run the test as described above
Windows:
--------
Sorry, no files here.
If you know how, you could copy the python or ruby example dsw & dsp and try editing that

View File

@@ -0,0 +1,21 @@
#include "base.h"
class Bar : public Base {
public:
Bar() { }
~Bar() { }
virtual const char * A() const {
return "Bar::A";
}
const char * B() const {
return "Bar::B";
}
virtual Base *toBase() {
return static_cast<Base *>(this);
}
static Bar *fromBase(Base *b) {
return dynamic_cast<Bar *>(b);
}
};

View File

@@ -0,0 +1,9 @@
%module bar
%{
#include "bar.h"
%}
%import base.i
%include "bar.h"

View File

@@ -0,0 +1,16 @@
class Base {
public:
Base() { }
virtual ~Base() { }
virtual const char * A() const {
return "Base::A";
}
const char * B() const {
return "Base::B";
}
virtual Base *toBase() {
return static_cast<Base *>(this);
}
};

View File

@@ -0,0 +1,6 @@
%module base
%{
#include "base.h"
%}
%include base.h

View File

@@ -0,0 +1,21 @@
#include "base.h"
class Foo : public Base {
public:
Foo() { }
~Foo() { }
virtual const char * A() const {
return "Foo::A";
}
const char * B() const {
return "Foo::B";
}
virtual Base *toBase() {
return static_cast<Base *>(this);
}
static Foo *fromBase(Base *b) {
return dynamic_cast<Foo *>(b);
}
};

View File

@@ -0,0 +1,8 @@
%module foo
%{
#include "foo.h"
%}
%import base.i
%include "foo.h"

View File

@@ -0,0 +1,103 @@
# Test various properties of classes defined in separate modules
print("Testing the %import directive")
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
function loadit(a)
lib=loadlib(a..'.dll','luaopen_'..a) or loadlib(a..'.so','luaopen_'..a)
assert(lib)()
end
loadit('base')
loadit('foo')
loadit('bar')
loadit('spam')
else
-- lua 5.1 does
require 'base'
require 'foo'
require 'bar'
require 'spam'
end
-- Create some objects
print("Creating some objects")
a = base.Base()
b = foo.Foo()
c = bar.Bar()
d = spam.Spam()
-- Try calling some methods
print("Testing some methods")
print("Should see 'Base::A' ---> ",a:A())
print("Should see 'Base::B' ---> ",a:B())
print("Should see 'Foo::A' ---> ",b:A())
print("Should see 'Foo::B' ---> ",b:B())
print("Should see 'Bar::A' ---> ",c:A())
print("Should see 'Bar::B' ---> ",c:B())
print("Should see 'Spam::A' ---> ",d:A())
print("Should see 'Spam::B' ---> ",d:B())
-- Try some casts
print("\nTesting some casts")
x = a:toBase()
print("Should see 'Base::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())
x = b:toBase()
print("Should see 'Foo::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())
x = c:toBase()
print("Should see 'Bar::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())
x = d:toBase()
print("Should see 'Spam::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())
x = d:toBar()
print("Should see 'Bar::B' ---> ",x:B())
print "\nTesting some dynamic casts\n"
x = d:toBase()
print " Spam -> Base -> Foo : "
y = foo.Foo_fromBase(x)
if y then
print "bad swig"
else
print "good swig"
end
print " Spam -> Base -> Bar : "
y = bar.Bar_fromBase(x)
if y then
print "good swig"
else
print "bad swig"
end
print " Spam -> Base -> Spam : "
y = spam.Spam_fromBase(x)
if y then
print "good swig"
else
print "bad swig"
end
print " Foo -> Spam : "
y = spam.Spam_fromBase(b)
if y then
print "bad swig"
else
print "good swig"
end

View File

@@ -0,0 +1,24 @@
#include "bar.h"
class Spam : public Bar {
public:
Spam() { }
~Spam() { }
virtual const char * A() const {
return "Spam::A";
}
const char * B() const {
return "Spam::B";
}
virtual Base *toBase() {
return static_cast<Base *>(this);
}
virtual Bar *toBar() {
return static_cast<Bar *>(this);
}
static Spam *fromBase(Base *b) {
return dynamic_cast<Spam *>(b);
}
};

View File

@@ -0,0 +1,9 @@
%module spam
%{
#include "spam.h"
%}
%import bar.i
%include "spam.h"

View File

@@ -0,0 +1,438 @@
/*
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lua_c
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** generic extra include file
*/
#ifdef LUA_USERCONFIG
#include LUA_USERCONFIG
#endif
/*
** definition of `isatty'
*/
#ifdef _POSIX_C_SOURCE
#include <unistd.h>
#define stdin_is_tty() isatty(0)
#else
#define stdin_is_tty() 1 /* assume stdin is a tty */
#endif
#ifndef PROMPT
#define PROMPT "> "
#endif
#ifndef PROMPT2
#define PROMPT2 ">> "
#endif
#ifndef PROGNAME
#define PROGNAME "lua"
#endif
#ifndef lua_userinit
#define lua_userinit(L) openstdlibs(L)
#endif
#ifndef LUA_EXTRALIBS
#define LUA_EXTRALIBS /* empty */
#endif
static lua_State *L = NULL;
static const char *progname = PROGNAME;
extern int Example_Init(lua_State* L);
static const luaL_reg lualibs[] = {
{"base", luaopen_base},
{"table", luaopen_table},
{"io", luaopen_io},
{"string", luaopen_string},
{"math", luaopen_math},
{"debug", luaopen_debug},
{"loadlib", luaopen_loadlib},
/* add your libraries here */
{"example", Example_Init},
LUA_EXTRALIBS
{NULL, NULL}
};
static void lstop (lua_State *l, lua_Debug *ar) {
(void)ar; /* unused arg. */
lua_sethook(l, NULL, 0, 0);
luaL_error(l, "interrupted!");
}
static void laction (int i) {
signal(i, SIG_DFL); /* if another SIGINT happens before lstop,
terminate process (default action) */
lua_sethook(L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
static void print_usage (void) {
fprintf(stderr,
"usage: %s [options] [script [args]].\n"
"Available options are:\n"
" - execute stdin as a file\n"
" -e stat execute string `stat'\n"
" -i enter interactive mode after executing `script'\n"
" -l name load and run library `name'\n"
" -v show version information\n"
" -- stop handling options\n" ,
progname);
}
static void l_message (const char *pname, const char *msg) {
if (pname) fprintf(stderr, "%s: ", pname);
fprintf(stderr, "%s\n", msg);
}
static int report (int status) {
const char *msg;
if (status) {
msg = lua_tostring(L, -1);
if (msg == NULL) msg = "(error with no message)";
l_message(progname, msg);
lua_pop(L, 1);
}
return status;
}
static int lcall (int narg, int clear) {
int status;
int base = lua_gettop(L) - narg; /* function index */
lua_pushliteral(L, "_TRACEBACK");
lua_rawget(L, LUA_GLOBALSINDEX); /* get traceback function */
lua_insert(L, base); /* put it under chunk and args */
signal(SIGINT, laction);
status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
signal(SIGINT, SIG_DFL);
lua_remove(L, base); /* remove traceback function */
return status;
}
static void print_version (void) {
l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT);
}
static void getargs (char *argv[], int n) {
int i;
lua_newtable(L);
for (i=0; argv[i]; i++) {
lua_pushnumber(L, i - n);
lua_pushstring(L, argv[i]);
lua_rawset(L, -3);
}
/* arg.n = maximum index in table `arg' */
lua_pushliteral(L, "n");
lua_pushnumber(L, i-n-1);
lua_rawset(L, -3);
}
static int docall (int status) {
if (status == 0) status = lcall(0, 1);
return report(status);
}
static int file_input (const char *name) {
return docall(luaL_loadfile(L, name));
}
static int dostring (const char *s, const char *name) {
return docall(luaL_loadbuffer(L, s, strlen(s), name));
}
static int load_file (const char *name) {
lua_pushliteral(L, "require");
lua_rawget(L, LUA_GLOBALSINDEX);
if (!lua_isfunction(L, -1)) { /* no `require' defined? */
lua_pop(L, 1);
return file_input(name);
}
else {
lua_pushstring(L, name);
return report(lcall(1, 1));
}
}
/*
** this macro can be used by some `history' system to save lines
** read in manual input
*/
#ifndef lua_saveline
#define lua_saveline(L,line) /* empty */
#endif
/*
** this macro defines a function to show the prompt and reads the
** next line for manual input
*/
#ifndef lua_readline
#define lua_readline(L,prompt) readline(L,prompt)
/* maximum length of an input line */
#ifndef MAXINPUT
#define MAXINPUT 512
#endif
static int readline (lua_State *l, const char *prompt) {
static char buffer[MAXINPUT];
if (prompt) {
fputs(prompt, stdout);
fflush(stdout);
}
if (fgets(buffer, sizeof(buffer), stdin) == NULL)
return 0; /* read fails */
else {
lua_pushstring(l, buffer);
return 1;
}
}
#endif
static const char *get_prompt (int firstline) {
const char *p = NULL;
lua_pushstring(L, firstline ? "_PROMPT" : "_PROMPT2");
lua_rawget(L, LUA_GLOBALSINDEX);
p = lua_tostring(L, -1);
if (p == NULL) p = (firstline ? PROMPT : PROMPT2);
lua_pop(L, 1); /* remove global */
return p;
}
static int incomplete (int status) {
if (status == LUA_ERRSYNTAX &&
strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) {
lua_pop(L, 1);
return 1;
}
else
return 0;
}
static int load_string (void) {
int status;
lua_settop(L, 0);
if (lua_readline(L, get_prompt(1)) == 0) /* no input? */
return -1;
if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */
lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */
lua_remove(L, -2); /* remove original line */
}
for (;;) { /* repeat until gets a complete line */
status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
if (!incomplete(status)) break; /* cannot try to add lines? */
if (lua_readline(L, get_prompt(0)) == 0) /* no more input? */
return -1;
lua_concat(L, lua_gettop(L)); /* join lines */
}
lua_saveline(L, lua_tostring(L, 1));
lua_remove(L, 1); /* remove line */
return status;
}
static void manual_input (void) {
int status;
const char *oldprogname = progname;
progname = NULL;
while ((status = load_string()) != -1) {
if (status == 0) status = lcall(0, 0);
report(status);
if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
l_message(progname, lua_pushfstring(L, "error calling `print' (%s)",
lua_tostring(L, -1)));
}
}
lua_settop(L, 0); /* clear stack */
fputs("\n", stdout);
progname = oldprogname;
}
static int handle_argv (char *argv[], int *interactive) {
if (argv[1] == NULL) { /* no more arguments? */
if (stdin_is_tty()) {
print_version();
manual_input();
}
else
file_input(NULL); /* executes stdin as a file */
}
else { /* other arguments; loop over them */
int i;
for (i = 1; argv[i] != NULL; i++) {
if (argv[i][0] != '-') break; /* not an option? */
switch (argv[i][1]) { /* option */
case '-': { /* `--' */
if (argv[i][2] != '\0') {
print_usage();
return 1;
}
i++; /* skip this argument */
goto endloop; /* stop handling arguments */
}
case '\0': {
file_input(NULL); /* executes stdin as a file */
break;
}
case 'i': {
*interactive = 1;
break;
}
case 'v': {
print_version();
break;
}
case 'e': {
const char *chunk = argv[i] + 2;
if (*chunk == '\0') chunk = argv[++i];
if (chunk == NULL) {
print_usage();
return 1;
}
if (dostring(chunk, "=<command line>") != 0)
return 1;
break;
}
case 'l': {
const char *filename = argv[i] + 2;
if (*filename == '\0') filename = argv[++i];
if (filename == NULL) {
print_usage();
return 1;
}
if (load_file(filename))
return 1; /* stop if file fails */
break;
}
case 'c': {
l_message(progname, "option `-c' is deprecated");
break;
}
case 's': {
l_message(progname, "option `-s' is deprecated");
break;
}
default: {
print_usage();
return 1;
}
}
} endloop:
if (argv[i] != NULL) {
const char *filename = argv[i];
getargs(argv, i); /* collect arguments */
lua_setglobal(L, "arg");
return file_input(filename); /* stop scanning arguments */
}
}
return 0;
}
static void openstdlibs (lua_State *l) {
const luaL_reg *lib = lualibs;
for (; lib->func; lib++) {
lib->func(l); /* open library */
lua_settop(l, 0); /* discard any results */
}
}
static int handle_luainit (void) {
const char *init = getenv("LUA_INIT");
if (init == NULL) return 0; /* status OK */
else if (init[0] == '@')
return file_input(init+1);
else
return dostring(init, "=LUA_INIT");
}
struct Smain {
int argc;
char **argv;
int status;
};
static int pmain (lua_State *l) {
struct Smain *s = (struct Smain *)lua_touserdata(l, 1);
int status;
int interactive = 0;
if (s->argv[0] && s->argv[0][0]) progname = s->argv[0];
L = l;
lua_userinit(l); /* open libraries */
status = handle_luainit();
if (status == 0) {
status = handle_argv(s->argv, &interactive);
if (status == 0 && interactive) manual_input();
}
s->status = status;
return 0;
}
int main (int argc, char *argv[]) {
int status;
struct Smain s;
lua_State *l = lua_open(); /* create state */
if (l == NULL) {
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
}
s.argc = argc;
s.argv = argv;
status = lua_cpcall(l, &pmain, &s);
report(status);
lua_close(l);
return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
}

View File

@@ -0,0 +1,22 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS =
TARGET = example
INTERFACE = example.i
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,23 @@
#ifndef _example_guardian_
#define _example_guardian_
int module_function() { return 7; }
int module_variable = 9;
namespace MyWorld {
class World {
public:
World() : world_max_count(9) {}
int create_world() { return 17; }
const int world_max_count; // = 9
};
namespace Nested {
class Dweller {
public:
enum Gender { MALE = 0, FEMALE = 1 };
static int count() { return 19; }
};
}
}
#endif

View File

@@ -0,0 +1,10 @@
%module example
%{
#include "example.h"
%}
%nspace MyWorld::Nested::Dweller;
%nspace MyWorld::World;
%include "example.h"

View File

@@ -0,0 +1,46 @@
-- file: runme.lua
-- This file illustrates class C++ interface generated
-- by SWIG.
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
ex = example
-- Calling a module function ( aka global function )
assert( ex.module_function() == 7 )
print("example.module_function(): ", ex.module_function())
-- Accessing a module (aka global) variable
assert( ex.module_variable == 9 )
print("example.module_variable: ", ex.module_variable)
-- Creating an instance of the class
w1 = ex.MyWorld.World()
print("Creating class instance: w1 = ex.MyWorld.World(): ", w1)
-- Accessing class members
assert( ex.MyWorld.World():create_world() == 17 )
print( "w1:create_world() = ", w1:create_world() )
assert( w1:create_world() == 17 )
print( "w1:world_max_count = ", w1.world_max_count )
assert( w1.world_max_count == 9 )
-- Accessing enums from class within namespace
print( "Accessing enums: ex.MyWorld.Nested.Dweller.MALE = ", ex.MyWorld.Nested.Dweller.MALE )
assert( ex.MyWorld.Nested.Dweller.MALE == 0 )
print( "Accessing enums: ex.MyWorld.Nested.Dweller.FEMALE = ", ex.MyWorld.Nested.Dweller.FEMALE )
assert( ex.MyWorld.Nested.Dweller.FEMALE == 1 )
-- Accessing static member function
print( "Accessing static member function: ex.MyWorld.Nested.Dweller.count() = ", ex.MyWorld.Nested.Dweller.count() )
assert( ex.MyWorld.Nested.Dweller.count() == 19 )

View File

@@ -0,0 +1,23 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
LIBS = -lm
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,72 @@
/* File : example.c */
#include "example.h"
#include <stdio.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(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;
}
Circle* createCircle(double w)
{
return new Circle(w);
}
Square* createSquare(double w)
{
return new Square(w);
}
ShapeOwner::ShapeOwner() {
printf(" ShapeOwner(%p)\n", (void *)this);
}
ShapeOwner::~ShapeOwner()
{
printf(" ~ShapeOwner(%p)\n", (void *)this);
for(unsigned i=0;i<shapes.size();i++)
delete shapes[i];
}
void ShapeOwner::add(Shape* ptr) // this method takes ownership of the object
{
shapes.push_back(ptr);
}
Shape* ShapeOwner::get(int idx) // this pointer is still owned by the class (assessor)
{
if (idx < 0 || idx >= static_cast<int>(shapes.size()))
return NULL;
return shapes[idx];
}
Shape* ShapeOwner::remove(int idx) // this method returns memory which must be deleted
{
if (idx < 0 || idx >= static_cast<int>(shapes.size()))
return NULL;
Shape* ptr=shapes[idx];
shapes.erase(shapes.begin()+idx);
return ptr;
}

View File

@@ -0,0 +1,54 @@
/* 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;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) { }
virtual double area(void);
virtual double perimeter(void);
};
class Square : public Shape {
private:
double width;
public:
Square(double w) : width(w) { }
virtual double area(void);
virtual double perimeter(void);
};
Circle* createCircle(double w); // this method creates a new object
Square* createSquare(double w); // this method creates a new object
class ShapeOwner {
private:
std::vector<Shape*> shapes;
ShapeOwner(const ShapeOwner&); // no copying
ShapeOwner& operator=(const ShapeOwner&); // no copying
public:
ShapeOwner();
~ShapeOwner();
void add(Shape* ptr); // this method takes ownership of the object
Shape* get(int idx); // this pointer is still owned by the class (assessor)
Shape* remove(int idx); // this method returns memory which must be deleted
};

View File

@@ -0,0 +1,32 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
// before we grab the header file, we must warn SWIG about some of these functions.
// these functions create data, so must be managed
%newobject createCircle;
%newobject createSquare;
// this method returns as pointer which must be managed
%newobject ShapeOwner::remove;
// you cannot use %delobject on ShapeOwner::add()
// as this disowns the ShapeOwner, not the Shape (oops)
//%delobject ShapeOwner::add(Shape*); DO NOT USE
// either you can use a new function (such as this)
/*%delobject add_Shape;
%inline %{
void add_Shape(Shape* s,ShapeOwner* own){own->add(s);}
%}*/
// or a better solution is a typemap
%apply SWIGTYPE *DISOWN {Shape* ptr};
// now we can grab the header file
%include "example.h"

View File

@@ -0,0 +1,104 @@
-- Operator overloading example
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
print "ok, let's test Lua's ownership of C++ objects"
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "\nLet's make a couple"
a=example.Square(10)
b=example.Circle(1)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 2)")
print "\nNote let's use the createX functions"
c=example.createCircle(5)
d=example.createSquare(3)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
print "\nWe will run the garbage collector & see if they are till here"
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
print "\nLet's get rid of them all, collect garbage & see if they are till here"
a,b,c,d=nil,nil,nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "\nLet's start putting stuff into the ShapeOwner"
print "The ShapeOwner now owns the shapes, but Lua still has pointers to them"
o=example.ShapeOwner()
a=example.Square(10)
b=example.Circle(1)
o:add(a)
o:add(b)
o:add(example.createSquare(5))
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nWe will nil our references,run the garbage collector & see if they are still here"
print "they should be, as the ShapeOwner owns them"
a,b=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nWe will access them and check that they are still valid"
a=o:get(0)
b=o:get(1)
print(" Area's are",a:area(),b:area(),o:get(2):area())
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nWe will remove one from the C++ owner & pass its ownership to Lua,"
print " then check that they are still unchanged"
a,b=nil,nil
a=o:remove(0) -- a now owns it
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
print "\nDelete the ShapeOwner (this should destroy two shapes),"
print " but we have one left in Lua"
o=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 1)")
print "\nFinal tidy up "
a=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "Final test, we will create some Shapes & pass them around like mad"
print "If there is any memory leak, you will see it in the memory usage"
io.flush()
sh={}
-- make some objects
for i=0,10 do
a=example.Circle(i)
b=example.Square(i)
sh[a]=true
sh[b]=true
end
o=example.ShapeOwner()
for i=0,10000 do
for k,_ in pairs(sh) do
o:add(k)
end
sh={} -- clear it
while true do
a=o:remove(0)
if a==nil then break end
sh[a]=true
end
if i%100==0 then collectgarbage() end
end
print "done"
o,sh=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "that's all folks!"

View File

@@ -0,0 +1,23 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
LIBS =
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

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

View File

@@ -0,0 +1,35 @@
/* File : example.i */
%module example
%{
#include <stdlib.h>
%}
/* This example illustrates a couple of different techniques
for manipulating C pointers */
/* First we'll use the pointer library */
%inline %{
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);
%{
extern void sub(int *, int *, int *);
%}
/* Next we'll use typemaps and the %apply directive */
%apply int *OUTPUT { int *r };
%inline %{
extern int divide(int n, int d, int *r);
%}

View File

@@ -0,0 +1,48 @@
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
-- First create some objects using the pointer library.
print("Testing the pointer library")
a = example.new_intp()
b = example.new_intp()
c = example.new_intp()
example.intp_assign(a,37)
example.intp_assign(b,42)
print(" a = "..tostring(a))
print(" b = "..tostring(b))
print(" c = "..tostring(c))
-- Call the add() function with some pointers
example.add(a,b,c)
-- Now get the result
r = example.intp_value(c)
print(" 37 + 42 = "..r)
-- Clean up the pointers
-- since this is C-style pointers you must clean it up
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")
r = example.sub(37,42)
print(" 37 - 42 = "..r)
-- Now try the version with multiple return values
print("Testing multiple return values")
q,r = example.divide(42,37)
print(" 42/37 = "..q.." remainder "..r)

View File

@@ -0,0 +1,22 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,18 @@
/* File : example.c */
/* A global variable */
double Foo = 3.0;
/* Compute the greatest common divisor of positive integers */
int gcd(int x, int y) {
int g;
g = y;
while (x > 0) {
g = x;
x = y % x;
y = g;
}
return g;
}

View File

@@ -0,0 +1,7 @@
/* File : example.i */
%module example
%inline %{
extern int gcd(int x, int y);
extern double Foo;
%}

View File

@@ -0,0 +1,35 @@
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
-- Call our gcd() function
x = 42
y = 105
g = example.gcd(x,y)
print("The gcd of",x,"and",y,"is",g)
-- Manipulate the Foo global variable
-- Output its current value
print("Foo = ", example.Foo)
-- Change its value
example.Foo = 3.1415926
-- See if the change took effect
print("Foo = ", example.Foo)

View File

@@ -0,0 +1,22 @@
TOP = ../..
SWIGEXE = $(TOP)/../swig
SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
SRCS = example.c
TARGET = example
INTERFACE = example.i
check: build
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_run
build:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
static:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
clean:
$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' lua_clean

View File

@@ -0,0 +1,91 @@
/* File : example.c */
/* I'm a file containing some C global variables */
/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
# define _CRT_SECURE_NO_DEPRECATE
#endif
#include <stdio.h>
#include <stdlib.h>
#include "example.h"
int ivar = 0;
short svar = 0;
long lvar = 0;
unsigned int uivar = 0;
unsigned short usvar = 0;
unsigned long ulvar = 0;
signed char scvar = 0;
unsigned char ucvar = 0;
char cvar = 0;
float fvar = 0;
double dvar = 0;
char *strvar = 0;
const char cstrvar[] = "Goodbye";
int *iptrvar = 0;
char name[256] = "Dave";
char path[256] = "/home/beazley";
/* Global variables involving a structure */
Point *ptptr = 0;
Point pt = { 10, 20 };
/* A variable that we will make read-only in the interface */
int status = 1;
/* A debugging function to print out their values */
void print_vars() {
printf("ivar = %d\n", ivar);
printf("svar = %d\n", svar);
printf("lvar = %ld\n", lvar);
printf("uivar = %u\n", uivar);
printf("usvar = %u\n", usvar);
printf("ulvar = %lu\n", ulvar);
printf("scvar = %d\n", scvar);
printf("ucvar = %u\n", ucvar);
printf("fvar = %g\n", fvar);
printf("dvar = %g\n", dvar);
printf("cvar = %c\n", cvar);
printf("strvar = %s\n", strvar ? strvar : "(null)");
printf("cstrvar = %s\n", cstrvar);
printf("iptrvar = %p\n", (void *)iptrvar);
printf("name = %s\n", name);
printf("ptptr = %p (%d, %d)\n", (void *)ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0);
printf("pt = (%d, %d)\n", pt.x, pt.y);
printf("status = %d\n", status);
}
/* A function to create an integer (to test iptrvar) */
int *new_int(int value) {
int *ip = (int *) malloc(sizeof(int));
*ip = value;
return ip;
}
/* A function to create a point */
Point *new_Point(int x, int y) {
Point *p = (Point *) malloc(sizeof(Point));
p->x = x;
p->y = y;
return p;
}
char * Point_print(Point *p) {
static char buffer[256];
if (p) {
sprintf(buffer,"(%d,%d)", p->x,p->y);
} else {
sprintf(buffer,"null");
}
return buffer;
}
void pt_print() {
printf("(%d, %d)\n", pt.x, pt.y);
}

View File

@@ -0,0 +1,6 @@
/* File: example.h */
typedef struct {
int x,y;
} Point;

View File

@@ -0,0 +1,49 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Some global variable declarations */
%inline %{
extern int ivar;
extern short svar;
extern long lvar;
extern unsigned int uivar;
extern unsigned short usvar;
extern unsigned long ulvar;
extern signed char scvar;
extern unsigned char ucvar;
extern char cvar;
extern float fvar;
extern double dvar;
extern char *strvar;
extern const char cstrvar[];
extern int *iptrvar;
extern char name[256];
extern Point *ptptr;
extern Point pt;
%}
/* Some read-only variables */
%immutable;
%inline %{
extern int status;
extern char path[256];
%}
%mutable;
/* Some helper functions to make it easier to test */
%inline %{
extern void print_vars();
extern int *new_int(int value);
extern Point *new_Point(int x, int y);
extern char *Point_print(Point *p);
extern void pt_print();
%}

View File

@@ -0,0 +1,81 @@
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesn't have a nice way to do this
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
assert(lib)()
else
-- lua 5.1 does
require('example')
end
-- Try to set the values of some global variables
example.ivar = 42
example.svar = -31000
example.lvar = 65537
example.uivar = 123456
example.usvar = 61000
example.ulvar = 654321
example.scvar = -13
example.ucvar = 251
example.cvar = "S"
example.fvar = 3.14159
example.dvar = 2.1828
example.strvar = "Hello World"
example.iptrvar= example.new_int(37)
example.ptptr = example.new_Point(37,42)
example.name = "Bill"
-- Now print out the values of the variables
print("Variables (values printed from Lua)")
print("ivar =", example.ivar)
print("svar =", example.svar)
print("lvar =", example.lvar)
print("uivar =", example.uivar)
print("usvar =", example.usvar)
print("ulvar =", example.ulvar)
print("scvar =", example.scvar)
print("ucvar =", example.ucvar)
print("fvar =", example.fvar)
print("dvar =", example.dvar)
print("cvar =", example.cvar)
print("strvar =", example.strvar)
print("cstrvar =", example.cstrvar)
print("iptrvar =", example.iptrvar)
print("name =", example.name)
print("ptptr =", example.ptptr, example.Point_print(example.ptptr))
print("pt =", example.pt, example.Point_print(example.pt))
print("\nVariables (values printed from C)")
example.print_vars()
print "\nNow I'm going to try and modify some read only variables";
print " Trying to set 'path' to 'Whoa!'";
if pcall(function() example.path = "Whoa!" end)==true then
print " That's funny, it didn't give an error!"
else
print " It gave an error, as it should"
end
print(" Just checking the value: path =", example.path)
print " Trying to set 'status' to '0'";
if pcall(function() example.status = 0 end)==true then
print " That's funny, it didn't give an error!"
else
print " It gave an error, as it should"
end
print(" Just checking the value: status =", example.status)
print "\nI'm going to try and update a structure variable.\n"
example.pt = example.ptptr
print "The new value is"
example.pt_print()
print("You should see the value", example.Point_print(example.ptptr))