/trunk/Examples/lua/embed2/embed2.c
C | 233 lines | 173 code | 24 blank | 36 comment | 19 complexity | e4b0c793e26ab99e7c01c2a0bb27e4e4 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.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;
- }