PageRenderTime 27ms CodeModel.GetById 15ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/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}