Convert to unix fileformat
This commit is contained in:
parent
bd67f57921
commit
079165abe2
22 changed files with 2479 additions and 2479 deletions
|
|
@ -1,18 +1,18 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
SRCS = example.c
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
|
||||
|
||||
static::
|
||||
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
|
||||
|
||||
clean::
|
||||
$(MAKE) -f $(TOP)/Makefile lua_clean
|
||||
|
||||
check: all
|
||||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
SRCS = example.c
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
|
||||
|
||||
static::
|
||||
$(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
|
||||
|
||||
clean::
|
||||
$(MAKE) -f $(TOP)/Makefile lua_clean
|
||||
|
||||
check: all
|
||||
|
|
|
|||
|
|
@ -1,25 +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);
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +1,42 @@
|
|||
/* 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
|
||||
// addmittedly 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
|
||||
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 indea
|
||||
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 indea
|
||||
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);
|
||||
%}
|
||||
/* 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
|
||||
// addmittedly 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
|
||||
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 indea
|
||||
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 indea
|
||||
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);
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -1,74 +1,74 @@
|
|||
---- importing ----
|
||||
if string.sub(_VERSION,1,7)=='Lua 5.0' then
|
||||
-- lua5.0 doesnt 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
|
||||
lets 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)
|
||||
|
||||
---- importing ----
|
||||
if string.sub(_VERSION,1,7)=='Lua 5.0' then
|
||||
-- lua5.0 doesnt 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
|
||||
lets 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)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,85 +1,85 @@
|
|||
/* embed.c a simple test for an embeded 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 wrappered 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 <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
|
||||
/* 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 its lua_dostring()
|
||||
In lua 5.1.X its 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 wrappered library\n");
|
||||
luaopen_example(L);
|
||||
printf("[C] all looks ok\n");
|
||||
printf("\n");
|
||||
printf("[C] lets load the file 'runme.lua'\n");
|
||||
printf("[C] any lua code in this file will be executed\n");
|
||||
if (luaL_loadfile(L, "runme.lua") || 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] lets 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] Lets 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] Lets 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;
|
||||
}
|
||||
/* embed.c a simple test for an embeded 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 wrappered 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 <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
|
||||
/* 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 its lua_dostring()
|
||||
In lua 5.1.X its 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 wrappered library\n");
|
||||
luaopen_example(L);
|
||||
printf("[C] all looks ok\n");
|
||||
printf("\n");
|
||||
printf("[C] lets load the file 'runme.lua'\n");
|
||||
printf("[C] any lua code in this file will be executed\n");
|
||||
if (luaL_loadfile(L, "runme.lua") || 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] lets 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] Lets 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] Lets 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +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");
|
||||
}
|
||||
/* 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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,233 +1,233 @@
|
|||
/* embed2.c some more test for an embeded 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 wrappered 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 <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* the SWIG wrappered 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 involded.
|
||||
(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_pushstring(L, "add"); /* function name */
|
||||
lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */
|
||||
if (!lua_isfunction(L,-1)) {
|
||||
printf("[C] error: cannot find function 'add'\n");
|
||||
lua_settop(L,top); // reset
|
||||
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); // reset
|
||||
return 0;
|
||||
}
|
||||
// check results
|
||||
if (!lua_isnumber(L,-1)) {
|
||||
printf("[C] error: returned value is not a number\n");
|
||||
lua_settop(L,top); // reset
|
||||
return 0;
|
||||
}
|
||||
*res=(int)lua_tonumber(L,-1);
|
||||
lua_settop(L,top); /* reset stack */
|
||||
return 1; // ok
|
||||
}
|
||||
|
||||
/* 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 its 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");
|
||||
printf("[C] lets load the file 'runme.lua'\n");
|
||||
printf("[C] any lua code in this file will be executed\n");
|
||||
if (luaL_loadfile(L, "runme.lua") || 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] lets 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] lets 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;
|
||||
}
|
||||
/* embed2.c some more test for an embeded 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 wrappered 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 <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* the SWIG wrappered 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 involded.
|
||||
(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_pushstring(L, "add"); /* function name */
|
||||
lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */
|
||||
if (!lua_isfunction(L,-1)) {
|
||||
printf("[C] error: cannot find function 'add'\n");
|
||||
lua_settop(L,top); // reset
|
||||
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); // reset
|
||||
return 0;
|
||||
}
|
||||
// check results
|
||||
if (!lua_isnumber(L,-1)) {
|
||||
printf("[C] error: returned value is not a number\n");
|
||||
lua_settop(L,top); // reset
|
||||
return 0;
|
||||
}
|
||||
*res=(int)lua_tonumber(L,-1);
|
||||
lua_settop(L,top); /* reset stack */
|
||||
return 1; // ok
|
||||
}
|
||||
|
||||
/* 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 its 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");
|
||||
printf("[C] lets load the file 'runme.lua'\n");
|
||||
printf("[C] any lua code in this file will be executed\n");
|
||||
if (luaL_loadfile(L, "runme.lua") || 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] lets 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] lets 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +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");
|
||||
}
|
||||
/* 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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "example.h"
|
||||
/* File : example.i */
|
||||
%module example
|
||||
|
||||
%{
|
||||
#include "example.h"
|
||||
%}
|
||||
|
||||
%include "example.h"
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
CXXSRCS =
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS = -lm
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
|
||||
|
||||
static::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
|
||||
|
||||
clean::
|
||||
$(MAKE) -f $(TOP)/Makefile lua_clean
|
||||
|
||||
check: all
|
||||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
CXXSRCS =
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS = -lm
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
|
||||
|
||||
static::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
|
||||
|
||||
clean::
|
||||
$(MAKE) -f $(TOP)/Makefile lua_clean
|
||||
|
||||
check: all
|
||||
|
|
|
|||
|
|
@ -1,53 +1,53 @@
|
|||
/* File : example.h */
|
||||
|
||||
#include <string>
|
||||
#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];
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
|
||||
class Test {
|
||||
public:
|
||||
int simple() throw(int&) {
|
||||
throw(37);
|
||||
return 1;
|
||||
}
|
||||
int message() throw(const char *) {
|
||||
throw("I died.");
|
||||
return 1;
|
||||
}
|
||||
int hosed() throw(Exc) {
|
||||
throw(Exc(42,"Hosed"));
|
||||
return 1;
|
||||
}
|
||||
int unknown() throw(A*) {
|
||||
static A a;
|
||||
throw &a;
|
||||
return 1;
|
||||
}
|
||||
int multi(int x) throw(int, const char *, Exc) {
|
||||
if (x == 1) throw(37);
|
||||
if (x == 2) throw("Bleah!");
|
||||
if (x == 3) throw(Exc(42,"No-go-diggy-die"));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
|
||||
/* File : example.h */
|
||||
|
||||
#include <string>
|
||||
#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];
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
|
||||
class Test {
|
||||
public:
|
||||
int simple() throw(int&) {
|
||||
throw(37);
|
||||
return 1;
|
||||
}
|
||||
int message() throw(const char *) {
|
||||
throw("I died.");
|
||||
return 1;
|
||||
}
|
||||
int hosed() throw(Exc) {
|
||||
throw(Exc(42,"Hosed"));
|
||||
return 1;
|
||||
}
|
||||
int unknown() throw(A*) {
|
||||
static A a;
|
||||
throw &a;
|
||||
return 1;
|
||||
}
|
||||
int multi(int x) throw(int, const char *, Exc) {
|
||||
if (x == 1) throw(37);
|
||||
if (x == 2) throw("Bleah!");
|
||||
if (x == 3) throw(Exc(42,"No-go-diggy-die"));
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
/* 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};
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
%include "example.h"
|
||||
|
||||
/* 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};
|
||||
|
||||
/* Let's just grab the original header file here */
|
||||
%include "example.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,96 +1,96 @@
|
|||
-- file: example.lua
|
||||
|
||||
---- importing ----
|
||||
if string.sub(_VERSION,1,7)=='Lua 5.0' then
|
||||
-- lua5.0 doesnt 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:mutli()"
|
||||
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 lets 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 lets 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)
|
||||
-- file: example.lua
|
||||
|
||||
---- importing ----
|
||||
if string.sub(_VERSION,1,7)=='Lua 5.0' then
|
||||
-- lua5.0 doesnt 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:mutli()"
|
||||
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 lets 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 lets 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)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS = -lm
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
|
||||
|
||||
static::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
|
||||
|
||||
clean::
|
||||
$(MAKE) -f $(TOP)/Makefile lua_clean
|
||||
|
||||
check: all
|
||||
TOP = ../..
|
||||
SWIG = $(TOP)/../preinst-swig
|
||||
CXXSRCS = example.cxx
|
||||
TARGET = example
|
||||
INTERFACE = example.i
|
||||
LIBS = -lm
|
||||
|
||||
all::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
|
||||
|
||||
static::
|
||||
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
|
||||
|
||||
clean::
|
||||
$(MAKE) -f $(TOP)/Makefile lua_clean
|
||||
|
||||
check: all
|
||||
|
|
|
|||
|
|
@ -1,69 +1,69 @@
|
|||
/* 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",this);}
|
||||
ShapeOwner::~ShapeOwner()
|
||||
{
|
||||
printf(" ~ShapeOwner(%p)\n",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;
|
||||
}
|
||||
/* 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",this);}
|
||||
ShapeOwner::~ShapeOwner()
|
||||
{
|
||||
printf(" ~ShapeOwner(%p)\n",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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,54 +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
|
||||
};
|
||||
|
||||
|
||||
/* 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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,32 +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"
|
||||
|
||||
/* 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"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,104 +1,104 @@
|
|||
-- Operator overloading example
|
||||
---- importing ----
|
||||
if string.sub(_VERSION,1,7)=='Lua 5.0' then
|
||||
-- lua5.0 doesnt 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, lets test Lua's ownership of C++ objects"
|
||||
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
|
||||
|
||||
print "\nLets 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 lets 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 "\nLets 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 "\nLets 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 till 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 "thats all folks!"
|
||||
-- Operator overloading example
|
||||
---- importing ----
|
||||
if string.sub(_VERSION,1,7)=='Lua 5.0' then
|
||||
-- lua5.0 doesnt 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, lets test Lua's ownership of C++ objects"
|
||||
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
|
||||
|
||||
print "\nLets 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 lets 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 "\nLets 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 "\nLets 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 till 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 "thats all folks!"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue