/trunk/Examples/lua/embed2/embed2.c
C | 233 lines | 173 code | 24 blank | 36 comment | 19 complexity | e4b0c793e26ab99e7c01c2a0bb27e4e4 MD5 | raw file
1/* embed2.c some more test for an embeded interpreter 2 3This will go a bit further as it will pass values to and from the lua code. 4It uses less of the SWIG code, and more of the raw lua API's 5 6What it will do is load the wrappered lib, load runme.lua and then call some functions. 7To make life easier, all the printf's have either [C] or [Lua] at the start 8so you can see where they are coming from. 9 10We will be using the luaL_dostring()/lua_dostring() function to call into lua 11 12*/ 13 14/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ 15#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) 16# define _CRT_SECURE_NO_DEPRECATE 17#endif 18 19/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ 20#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) 21# define _SCL_SECURE_NO_DEPRECATE 22#endif 23 24 25#include <stdlib.h> 26#include <stdio.h> 27 28#include <lua.h> 29#include <lauxlib.h> 30#include <lualib.h> 31#include <stdarg.h> 32#include <string.h> 33 34 35/* the SWIG wrappered library */ 36extern int luaopen_example(lua_State*L); 37 38/* This is an example of how to call the Lua function 39 int add(int,int) 40 its very tedious, but gives you an idea of the issues involded. 41 (look below for a better idea) 42*/ 43int call_add(lua_State *L,int a,int b,int* res) { 44 int top; 45 /* ok, here we go: 46 push a, push b, call 'add' check & return res 47 */ 48 top=lua_gettop(L); /* for later */ 49 lua_pushstring(L, "add"); /* function name */ 50 lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */ 51 if (!lua_isfunction(L,-1)) { 52 printf("[C] error: cannot find function 'add'\n"); 53 lua_settop(L,top); // reset 54 return 0; 55 } 56 lua_pushnumber(L,a); 57 lua_pushnumber(L,b); 58 if (lua_pcall(L, 2, 1, 0) != 0) /* call function with 2 arguments and 1 result */ 59 { 60 printf("[C] error running function `add': %s\n",lua_tostring(L, -1)); 61 lua_settop(L,top); // reset 62 return 0; 63 } 64 // check results 65 if (!lua_isnumber(L,-1)) { 66 printf("[C] error: returned value is not a number\n"); 67 lua_settop(L,top); // reset 68 return 0; 69 } 70 *res=(int)lua_tonumber(L,-1); 71 lua_settop(L,top); /* reset stack */ 72 return 1; // ok 73} 74 75/* This is a variargs call function for calling from C into Lua. 76Original Code from Programming in Lua (PIL) by Roberto Ierusalimschy 77ISBN 85-903798-1-7 78http://www.lua.org/pil/25.3.html 79This has been modified slightly to make it compile, and its still a bit rough. 80But it gives the idea of how to make it work. 81*/ 82int call_va (lua_State *L,const char *func, const char *sig, ...) { 83 va_list vl; 84 int narg, nres; /* number of arguments and results */ 85 int top; 86 top=lua_gettop(L); /* for later */ 87 88 va_start(vl, sig); 89 lua_getglobal(L, func); /* get function */ 90 91 /* push arguments */ 92 narg = 0; 93 while (*sig) { /* push arguments */ 94 switch (*sig++) { 95 96 case 'd': /* double argument */ 97 lua_pushnumber(L, va_arg(vl, double)); 98 break; 99 100 case 'i': /* int argument */ 101 lua_pushnumber(L, va_arg(vl, int)); 102 break; 103 104 case 's': /* string argument */ 105 lua_pushstring(L, va_arg(vl, char *)); 106 break; 107 108 case '>': 109 goto endwhile; 110 111 default: 112 printf("invalid option (%c)\n", *(sig - 1)); 113 goto fail; 114 } 115 narg++; 116 /* do we need this?*/ 117 /* luaL_checkstack(L, 1, "too many arguments"); */ 118 } 119endwhile: 120 121 /* do the call */ 122 nres = (int)strlen(sig); /* number of expected results */ 123 if (lua_pcall(L, narg, nres, 0) != 0) /* do the call */ 124 { 125 printf("error running function `%s': %s\n",func, lua_tostring(L, -1)); 126 goto fail; 127 } 128 129 /* retrieve results */ 130 nres = -nres; /* stack index of first result */ 131 while (*sig) { /* get results */ 132 switch (*sig++) { 133 134 case 'd': /* double result */ 135 if (!lua_isnumber(L, nres)) { 136 printf("wrong result type\n"); 137 goto fail; 138 } 139 *va_arg(vl, double *) = lua_tonumber(L, nres); 140 break; 141 142 case 'i': /* int result */ 143 if (!lua_isnumber(L, nres)) { 144 printf("wrong result type\n"); 145 goto fail; 146 } 147 *va_arg(vl, int *) = (int)lua_tonumber(L, nres); 148 break; 149 150 case 's': /* string result */ 151 if (!lua_isstring(L, nres)) { 152 printf("wrong result type\n"); 153 goto fail; 154 } 155 strcpy(va_arg(vl, char *),lua_tostring(L, nres));/* WARNING possible buffer overflow */ 156 break; 157 158 default: { 159 printf("invalid option (%c)", *(sig - 1)); 160 goto fail; 161 } 162 } 163 nres++; 164 } 165 va_end(vl); 166 167 lua_settop(L,top); /* reset stack */ 168 return 1; /* ok */ 169fail: 170 lua_settop(L,top); /* reset stack */ 171 return 0; /* error */ 172} 173 174int main(int argc,char* argv[]) { 175 lua_State *L; 176 int ok; 177 int res; 178 char str[80]; 179 printf("[C] Welcome to the simple embedded Lua example v2\n"); 180 printf("[C] We are in C\n"); 181 printf("[C] opening a Lua state & loading the libraries\n"); 182 L=lua_open(); 183 luaopen_base(L); 184 luaopen_string(L); 185 luaopen_math(L); 186 printf("[C] now loading the SWIG wrappered library\n"); 187 luaopen_example(L); 188 printf("[C] all looks ok\n"); 189 printf("\n"); 190 printf("[C] lets load the file 'runme.lua'\n"); 191 printf("[C] any lua code in this file will be executed\n"); 192 if (luaL_loadfile(L, "runme.lua") || lua_pcall(L, 0, 0, 0)) { 193 printf("[C] ERROR: cannot run lua file: %s",lua_tostring(L, -1)); 194 exit(3); 195 } 196 printf("[C] We are now back in C, all looks ok\n"); 197 printf("\n"); 198 printf("[C] lets call the Lua function 'add(1,1)'\n"); 199 printf("[C] using the C function 'call_add'\n"); 200 ok=call_add(L,1,1,&res); 201 printf("[C] the function returned %d with value %d\n",ok,res); 202 printf("\n"); 203 printf("[C] lets do this rather easier\n"); 204 printf("[C] we will call the same Lua function using a generic C function 'call_va'\n"); 205 ok=call_va(L,"add","ii>i",1,1,&res); 206 printf("[C] the function returned %d with value %d\n",ok,res); 207 printf("\n"); 208 printf("[C] we will now use the same generic C function to call 'append(\"cat\",\"dog\")'\n"); 209 ok=call_va(L,"append","ss>s","cat","dog",str); 210 printf("[C] the function returned %d with value %s\n",ok,str); 211 printf("\n"); 212 printf("[C] we can also make some bad calls to ensure the code doesn't fail\n"); 213 printf("[C] calling adds(1,2)\n"); 214 ok=call_va(L,"adds","ii>i",1,2,&res); 215 printf("[C] the function returned %d with value %d\n",ok,res); 216 printf("[C] calling add(1,'fred')\n"); 217 ok=call_va(L,"add","is>i",1,"fred",&res); 218 printf("[C] the function returned %d with value %d\n",ok,res); 219 printf("\n"); 220 printf("[C] Note: no protection if you mess up the va-args, this is C\n"); 221 printf("\n"); 222 printf("[C] Finally we will call the wrappered gcd function gdc(6,9):\n"); 223 printf("[C] This will pass the values to Lua, then call the wrappered function\n"); 224 printf(" Which will get the values from Lua, call the C code \n"); 225 printf(" and return the value to Lua and eventually back to C\n"); 226 printf("[C] Certainly not the best way to do it :-)\n"); 227 ok=call_va(L,"gcd","ii>i",6,9,&res); 228 printf("[C] the function returned %d with value %d\n",ok,res); 229 printf("\n"); 230 printf("[C] all finished, closing the lua state\n"); 231 lua_close(L); 232 return 0; 233}