├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── Makefile ├── README.md ├── examples ├── example_basic.c ├── example_convert.c ├── example_embed.c ├── example_enum.c ├── example_func.c ├── example_mod.c ├── example_struct.c └── example_unnested.c ├── lautoc.c ├── lautoc.h ├── lautoc.lua ├── lautocall.h └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.o 3 | 4 | /config.mk 5 | /obj 6 | 7 | /lib*.a 8 | /lib*.so 9 | /examples/example_basic 10 | /examples/example_enum 11 | /examples/example_convert 12 | /examples/example_embed 13 | /examples/example_func 14 | /examples/example_struct 15 | /examples/example_mod 16 | /examples/example_unnested 17 | 18 | /*.lib 19 | /*.dll 20 | /examples/*.exe 21 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ---------- 3 | 4 | ### Changes from version 1 to 2 5 | 6 | The major change in this version is due to a change the internal hashtable 7 | utility, which was removed and all the internal metadata which LuaAutoC uses 8 | was instead put into the Lua registry and accessed using Lua tables. 9 | 10 | The two major advantages of this is that LuaAutoC no longer relies on 11 | static variables, and that all the meta-data about the LuaAutoC types 12 | can be found by looking into the registry either by C users or Lua users. 13 | 14 | Here is a brief (incomplete) change log intended for people porting code. 15 | 16 | * Removal of internal Hashtable. Instead all data is in the Lua registry in Lua tables 17 | * Merged all source files into single source file. Simplified build process. 18 | * Renamed header `lautofunc.h` to `lautocall.h`. 19 | * All open and close functions merged into `luaA_open` and `luaA_close` 20 | * All functions now take Lua state `L` as the first variable. 21 | * Functions that ended in `typeid` to indicate they take `luaA_Type` inputs now end in just `type` 22 | * Typedef of `luaA_Type` is now `lua_Integer`. 23 | * Renamed `luaA_typeid` to `luaA_type` 24 | * Renamed `luaA_type_name` to `luaA_typename`. 25 | * Renamed `luaA_type_size` to `luaA_typesize`. 26 | * Removed `luaA_struct_next`, this proved difficult to implement in the new system. 27 | * Enum functions no longer take case sensitive argument. Aliases should be used instead (`luaA_enum_value_name`). 28 | * Removed `luaA_function_void`. Use `luaA_function` and specify `void` as the return type. This is now dealt with automatically. 29 | * Removed `luaA_function_decl_void`. Use `luaA_function_declare` and specify `void` as the return type. This is now dealt with automatically. 30 | * Removed `luaA_function_reg_void`. Use `luaA_function_register` and specify `void` as the return type. This is now dealt with automatically. 31 | * Renamed `luaA_function_decl` to `luaA_function_declare`. 32 | * Renamed `luaA_function_reg` to `luaA_function_register`. 33 | * Function `luaA_function` no longer takes argument count. This is now found automatically. 34 | * Function `luaA_function_declare` no longer takes argument count. This is now found automatically. 35 | * Function `luaA_function_register` no longer takes argument count. This is now found automatically. 36 | * Exposed argument and return stack sizes for fake stack. 37 | * Renamed `demos` folder to `examples` and all the files within. 38 | * Changed `luaA_call` and `luaA_call_name` to remove their arguments from stack, only leaving return values. 39 | * Switched argument order to `luaA_struct_push_member` so that member comes before input. 40 | * Switched argument order to `luaA_struct_push_member_name` so that member comes before input. 41 | * Switched argument order to `luaA_struct_to_member` so that member comes before output. 42 | * Switched argument order to `luaA_struct_to_member_name` so that member comes before output. 43 | 44 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Daniel Holden 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | The views and conclusions contained in the software and documentation are those 25 | of the authors and should not be interpreted as representing official policies, 26 | either expressed or implied, of the FreeBSD Project. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | -include config.mk 2 | 3 | PLATFORM?= $(shell uname) 4 | 5 | CC?=gcc 6 | AR?=ar 7 | 8 | LAC=lautoc.c 9 | LAC_OBJ=lautoc.o 10 | LAC_CPPFLAGS= -I./include $(LUA_INCLUDE_DIR) 11 | LAC_CFLAGS= -std=gnu99 -Wall -Werror -Wno-unused -O3 -g 12 | LAC_LDFLAGS= $(LUA_LIBRARY_DIR) 13 | LAC_LIBS= $(LUA_LIBRARY) 14 | 15 | EXAMPLES_SRC= $(wildcard examples/*.c) 16 | EXAMPLES_OUT= $(EXAMPLES_SRC:%.c=%$(EXE_SUFFIX)) 17 | 18 | SHARED_LIB= $(SHARED_LIB_PREFIX)lautoc$(SHARED_LIB_SUFFIX) 19 | STATIC_LIB= $(STATIC_LIB_PREFIX)lautoc$(STATIC_LIB_SUFFIX) 20 | 21 | ifeq ($(findstring Linux,$(PLATFORM)),Linux) 22 | LUA_INCLUDE_DIR?= -I/usr/include/lua5.2/ 23 | LUA_LIBRARY?= -llua5.2 24 | LAC_CFLAGS+= -fPIC 25 | LAC_LDFLAGS+= -fPIC 26 | SHARED_LIB_PREFIX:=lib 27 | SHARED_LIB_SUFFIX:=.so 28 | STATIC_LIB_PREFIX:=lib 29 | STATIC_LIB_SUFFIX:=.a 30 | EXE_SUFFIX:= 31 | else ifeq ($(findstring Darwin,$(PLATFORM)),Darwin) 32 | LUA_INCLUDE_DIR?= -I/usr/include/lua5.2/ 33 | LUA_LIBRARY?= -llua5.2 34 | LAC_CFLAGS+= -fPIC 35 | LAC_LDFLAGS+= -fPIC 36 | SHARED_LIB_PREFIX:=lib 37 | SHARED_LIB_SUFFIX:=.so 38 | STATIC_LIB_PREFIX:=lib 39 | STATIC_LIB_SUFFIX:=.a 40 | EXE_SUFFIX:= 41 | else ifeq ($(findstring MINGW,$(PLATFORM)),MINGW) 42 | LUA_LIBRARY?= -llua 43 | LAC_LIBS+= -lmingw32 44 | SHARED_LIB_PREFIX:= 45 | SHARED_LIB_SUFFIX:=.dll 46 | STATIC_LIB_PREFIX:= 47 | STATIC_LIB_SUFFIX:=.lib 48 | EXE_SUFFIX:=.exe 49 | endif 50 | 51 | # Library 52 | 53 | all: $(SHARED_LIB) $(STATIC_LIB) 54 | 55 | $(SHARED_LIB): $(LAC) 56 | $(CC) $^ $(CFLAGS) $(LAC_CFLAGS) $(LAC_CPPFLAGS) $(LDFLAGS) $(LAC_LDFLAGS) $(LAC_LIBS) -shared -o $@ 57 | 58 | $(STATIC_LIB): $(LAC) 59 | $(CC) $^ $(CFLAGS) $(LAC_CFLAGS) $(LAC_CPPFLAGS) -c 60 | $(AR) rcs $@ $(LAC_OBJ) 61 | 62 | # Examples 63 | 64 | examples: $(EXAMPLES_OUT) 65 | 66 | examples/example_%$(EXE_SUFFIX): examples/example_%.c $(LAC) 67 | $(CC) $^ $(CFLAGS) $(LAC_CFLAGS) $(LAC_CPPFLAGS) $(LDFLAGS) $(LAC_LDFLAGS) $(LAC_LIBS) -o $@ 68 | 69 | # Clean 70 | 71 | clean: 72 | $(RM) $(LAC_OBJ) $(EXAMPLES_OUT) $(SHARED_LIB) $(STATIC_LIB) 73 | 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LuaAutoC 2 | ======== 3 | 4 | Automagically use C Functions and Structs with the Lua API 5 | 6 | Version 2.0.1 7 | 8 | ```c 9 | #include "lautoc.h" 10 | 11 | int fib(int n) { 12 | if (n == 0) { return 1; } 13 | if (n == 1) { return 1; } 14 | return fib(n-1) + fib(n-2); 15 | } 16 | 17 | int main(int argc, char** argv) { 18 | 19 | /* Init Lua & LuaAutoC */ 20 | lua_State* L = luaL_newstate(); 21 | luaA_open(L); 22 | 23 | /* Register `fib` function */ 24 | luaA_function(L, fib, int, int); 25 | 26 | /* Push integer onto stack and call `fib` */ 27 | lua_pushinteger(L, 25); 28 | luaA_call(L, fib); 29 | 30 | /* Print result & pop */ 31 | printf("Result: %i\n", (int)lua_tointeger(L, -1)); 32 | lua_pop(L, 1); 33 | 34 | luaA_close(L); 35 | lua_close(L); 36 | 37 | return 0; 38 | } 39 | ``` 40 | 41 | Features 42 | -------- 43 | 44 | * Friendly API. 45 | * Easy to integrate (1 source file, 2 headers). 46 | * Existing code is unaffected. 47 | * Flexible, Extensible and Powerful. 48 | * Provides dynamic runtime reflection. 49 | 50 | 51 | Usage 52 | ----- 53 | 54 | ### Functions 55 | 56 | At its most basic, LuaAutoC can be used to automatically call C functions from the Lua API. Lua stack arguments are automatically popped and converted to C types, the function is executed, and the return value is then converted back to a Lua type and placed on top the stack. First the function must be registered with `luaA_function`, and then at any point later it can be called with `luaA_call`. 57 | 58 | ```c 59 | #include "lautoc.h" 60 | 61 | float power(float val, int pow) { 62 | float x = 1.0; 63 | for(int i = 0; i < pow; i++) { 64 | x = x * val; 65 | } 66 | return x; 67 | } 68 | 69 | int main(int argc, char **argv) { 70 | 71 | lua_State* L = luaL_newstate(); 72 | luaA_open(L); 73 | 74 | luaA_function(L, power, float, float, int); 75 | 76 | lua_pushnumber(L, 4.2); 77 | lua_pushinteger(L, 3); 78 | luaA_call(L, power); 79 | 80 | printf("Result: %f\n", lua_tonumber(L, -1)); 81 | lua_pop(L, 1); 82 | 83 | luaA_close(L); 84 | lua_close(L); 85 | 86 | return 0; 87 | } 88 | ``` 89 | 90 | ### Structs 91 | 92 | LuaAutoC also provides functions to deal with structs. Their members can be pushed onto or read from the stack, with automatic conversion of types between Lua and C provided. 93 | 94 | ```c 95 | typedef struct { 96 | float x, y, z; 97 | } vec3; 98 | ``` 99 | 100 | As with functions first they need to be registered. 101 | 102 | ```c 103 | luaA_struct(L, vec3); 104 | luaA_struct_member(L, vec3, x, float); 105 | luaA_struct_member(L, vec3, y, float); 106 | luaA_struct_member(L, vec3, z, float); 107 | ``` 108 | 109 | And then they can be used with the Lua API. 110 | 111 | ```c 112 | vec3 pos = {1.0f, 2.11f, 3.16f}; 113 | 114 | luaA_struct_push_member(L, vec3, x, &pos); 115 | printf("x: %f\n", lua_tonumber(L, -1)); 116 | lua_pop(L, 1); 117 | 118 | lua_pushnumber(L, 0.0); 119 | luaA_struct_to_member(L, vec3, x, &pos, -1); 120 | lua_pop(L, 1); 121 | 122 | luaA_struct_push_member(L, vec3, x, &pos); 123 | printf("x: %f\n", lua_tonumber(L, -1)); 124 | lua_pop(L, 1); 125 | ``` 126 | 127 | ### Conversion 128 | 129 | To use LuaAutoC with non-native types it is possible to register your own conversion functions. 130 | 131 | ```c 132 | typedef struct { 133 | int fst, snd; 134 | } pair; 135 | 136 | static int luaA_push_pair(lua_State* L, luaA_Type t, const void* c_in) { 137 | pair* p = (pair*)c_in; 138 | lua_pushinteger(L, p->fst); 139 | lua_pushinteger(L, p->snd); 140 | return 2; 141 | } 142 | 143 | static void luaA_to_pair(lua_State* L, luaA_Type t, void* c_out, int index) { 144 | pair* p = (pair*)c_out; 145 | p->snd = lua_tointeger(L, index); 146 | p->fst = lua_tointeger(L, index-1); 147 | } 148 | ``` 149 | 150 | These are registered with `luaA_conversion`. 151 | 152 | ```c 153 | luaA_conversion(L, pair, luaA_push_pair, luaA_to_pair); 154 | ``` 155 | 156 | And are then automatically used in the calling of functions, or in the conversion of structs and their members. Registered conversions are also available directly for manipulation of the Lua stack using `luaA_push` and `luaA_to`. For example to push a pair onto the stack... 157 | 158 | ```c 159 | pair p = {1, 2}; 160 | luaA_push(L, pair, &p); 161 | ``` 162 | 163 | Essentially registering a conversion is all that is required to make that type available from the whole of LuaAutoC. 164 | 165 | But who wants to write a bunch of conversion functions? When structs are registered with LuaAutoC, if no conversion functions are registered, automatic conversion to a Lua table is performed. So in reality writing conversions is a rare thing! 166 | 167 | ```c 168 | typedef struct { 169 | int id; 170 | int legs; 171 | float height; 172 | } table; 173 | ``` 174 | 175 | ```c 176 | luaA_struct(L, table); 177 | luaA_struct_member(L, table, id, int); 178 | luaA_struct_member(L, table, legs, int); 179 | luaA_struct_member(L, table, height, float); 180 | ``` 181 | 182 | ```c 183 | table t = {0, 4, 0.72}; 184 | 185 | luaA_push(L, table, &t); 186 | 187 | lua_getfield(L, -1, "legs"); 188 | printf("legs: %i\n", (int)lua_tointeger(L, -1)); 189 | lua_pop(L, 1); 190 | 191 | lua_getfield(L, -1, "height"); 192 | printf("height: %f\n", lua_tonumber(L, -1)); 193 | lua_pop(L, 1); 194 | 195 | lua_pop(L, 1); 196 | ``` 197 | 198 | This is very useful, but a few words of warning. 199 | 200 | * Be careful with circular references. The conversion is recursive and given the chance will happily run forever! 201 | * Be careful of pointer types such as `char*`. An automatic conversion may just assign a new pointer and might not do the intended behaviour, of copying the contents pointed to. This can sometimes screw up the garbage collector. 202 | 203 | ### Enums 204 | 205 | Enums can be used too. They are transformed into string, value mappings. 206 | 207 | Again they need to be registered. Multiple strings can be registered for a single value, and any matching Lua string will be transformed into the C value. But if a value has multiple strings, the last registered string will be used when transforming from C to Lua. 208 | 209 | ```c 210 | typedef enum { 211 | DIAMONDS, 212 | HEARTS, 213 | CLUBS, 214 | SPADES, 215 | INVALID = -1 216 | } cards; 217 | ``` 218 | 219 | ```c 220 | luaA_enum(L, cards); 221 | luaA_enum_value(L, cards, DIAMONDS); 222 | luaA_enum_value(L, cards, HEARTS); 223 | luaA_enum_value(L, cards, CLUBS); 224 | luaA_enum_value(L, cards, SPADES); 225 | luaA_enum_value(L, cards, INVALID); 226 | ``` 227 | 228 | ```c 229 | cards cval = SPADES; 230 | const char* lval = "SPADES"; 231 | 232 | luaA_push(L, cards, &cval); 233 | printf("%i pushed as %s\n", cval, lua_tostring(L, -1)); 234 | lua_pop(L, 1); 235 | 236 | lua_pushstring(L, lval); 237 | luaA_to(L, cards, &cval, -1); 238 | printf("%s read back as %i\n", lval, cval); 239 | lua_pop(L, 1); 240 | ``` 241 | 242 | ### Quick & Dirty Interface 243 | 244 | Because LuaAutoC stores meta-information and registered functions and types, this lets you call C functions just by providing a string of their name. Using this it is really easy to make a quick and dirty interface to your C library, which can later be extended and wrapped nicely on the Lua side of things. 245 | 246 | Given some set of functions. 247 | 248 | ```c 249 | /* Hello Module Begin */ 250 | 251 | void hello_world(void) { 252 | puts("Hello World!"); 253 | } 254 | 255 | void hello_repeat(int times) { 256 | for (int i = 0; i < times; i++) { 257 | hello_world(); 258 | } 259 | } 260 | 261 | void hello_person(const char* person) { 262 | printf("Hello %s!\n", person); 263 | } 264 | 265 | int hello_subcount(const char* greeting) { 266 | int count = 0; 267 | const char *tmp = greeting; 268 | while((tmp = strstr(tmp, "hello"))) { 269 | count++; tmp++; 270 | } 271 | return count; 272 | } 273 | 274 | /* Hello Module End */ 275 | ``` 276 | 277 | We can create a Lua function that takes some function name as a string, and some other arguments, and calls the matching C function with that name. 278 | 279 | ```c 280 | int C(lua_State* L) { 281 | return luaA_call_name(L, lua_tostring(L, 1)); 282 | } 283 | ``` 284 | 285 | We then just need to register those functions, and also register the `C` function to be available from Lua. 286 | 287 | ```c 288 | luaA_function(L, hello_world, void); 289 | luaA_function(L, hello_repeat, void, int); 290 | luaA_function(L, hello_person, void, const char*); 291 | luaA_function(L, hello_subcount, int, const char*); 292 | 293 | lua_register(L, "C", C); 294 | ``` 295 | 296 | And now we can call our C functions from Lua easily! 297 | 298 | ```c 299 | luaL_dostring(L, 300 | "C('hello_world')\n" 301 | "C('hello_person', 'Daniel')\n" 302 | "C('hello_repeat', C('hello_subcount', 'hello hello'))\n" 303 | ); 304 | ``` 305 | 306 | You can then wrap this function in whatever Lua interface you like. One nice idea is to create a table and set it's `__index` metamethod to return the C function of the same name. 307 | 308 | ```lua 309 | Hello = {} 310 | Hello.__index = function (table, key) 311 | return function (...) 312 | return C(key, ...) 313 | end 314 | end 315 | 316 | setmetatable(Hello, Hello) 317 | 318 | Hello.hello_world() 319 | Hello.hello_person('Marcelo') 320 | ``` 321 | 322 | ### Advanced Interface 323 | 324 | Using LuaAutoC it is easy to wrap pointers to structs so that they act like object instances. All we need to do is set `__index` and `__newindex` in the metatable. 325 | 326 | ```lua 327 | Birdie = {} 328 | setmetatable(Birdie, Birdie) 329 | 330 | function Birdie.__call() 331 | local self = {} 332 | setmetatable(self, Birdie) 333 | return self 334 | end 335 | 336 | Birdie.__index = birdie_index 337 | Birdie.__newindex = birdie_newindex 338 | 339 | bird = Birdie() 340 | print(bird.name) 341 | print(bird.num_wings) 342 | bird.num_wings = 3 343 | print(bird.num_wings) 344 | ``` 345 | 346 | Now we just define `birdie_index` and `birdie_newindex` in the C API as shown below. Alternatively developers can define the whole metatable in C and hide the `birdie_newindex` and `birdie_index` functions altogether. 347 | 348 | ```c 349 | typedef struct { 350 | char* name; 351 | int num_wings; 352 | } birdie; 353 | 354 | int birdie_index(lua_State* L) { 355 | const char* membername = lua_tostring(L, -1); 356 | birdie* self = get_instance_ptr(L); 357 | return luaA_struct_push_member_name(L, birdie, membername, self); 358 | } 359 | 360 | int birdie_newindex(lua_State* L) { 361 | const char* membername = lua_tostring(L, -2); 362 | birdie* self = get_instance_ptr(L); 363 | luaA_struct_to_member_name(L, birdie, membername, self, -1); 364 | return 0; 365 | } 366 | ``` 367 | 368 | ```c 369 | luaA_struct(L, birdie); 370 | luaA_struct_member(L, birdie, name, char*); 371 | luaA_struct_member(L, birdie, num_wings, int); 372 | 373 | lua_register(L, "birdie_index", birdie_index); 374 | lua_register(L, "birdie_newindex", birdie_newindex); 375 | ``` 376 | 377 | This is a great way to avoid having to write a bunch of getters and setters! 378 | 379 | The `get_instance_ptr` function is left for the user to implement and there are lots of options. The idea is that somehow the Lua table/instance should tell you how to get a pointer to the actual struct instance in C which it represents. A good option is to store C pointers in the Lua table. 380 | 381 | It is also possible to make the Lua metatable allocation and deallocation functions call some C functions which allocate and decallocate the structure you are emulating, storing the instance pointer to let you identify it later! Not only that. It isn't difficult to make methods available too! 382 | 383 | The true power of Lua AutoC comes if you look a level deeper. If you use `luaA_struct_push_member_name_type` or `luaA_truct_to_member_name_type` you can even generalize the above code to work for arbitrary structs/classes/types. Then when other developers create new structs and types, they can register them with your system to make them trivial to access from Lua. 384 | 385 | For this to work you need to get a `luaA_Type` value. This can be found by feeding a string into `luaA_type_find` which will lookup a string and see if a type has been registered with the same name. This means that if you give it a string of a previously registered data type E.G `"birdie"`, it will return a matching id. One trick is to feed it with the name of the instance's metatable. This means it is possible to create a new Lua object with defined `__index` and `__newindex`, it will automatically act like the corresponding C struct of the same name. 386 | 387 | ### Managing Behaviour 388 | 389 | Often in C, the same types can have different meanings. For example an `int*` could either mean that a function wants an array of integers or that it outputs some integer. We can change the behaviour of Lua AutoC without changing the function signature by using typedefs and new conversion functions. Then on function registration you just use the newly defined type rather than the old one. Providing the types are true aliases there won't be any problems with converting types. 390 | 391 | ```c 392 | static void print_int_list(int* list, int num_ints) { 393 | for(int i = 0; i < num_ints; i++) { 394 | printf("Int %i: %i\n", i, list[i]); 395 | } 396 | } 397 | 398 | typedef int* int_list; 399 | 400 | static int list_space[512]; 401 | static void luaA_to_int_list(lau_State* L, luaA_Type t, void* c_out, int index) { 402 | for(int i = 1; i <= luaL_getn(L, index); i++) { 403 | lua_pushinteger(L, i); 404 | lua_gettable(L, index-1); 405 | list_space[i] = lua_tointeger(L, index); lua_pop(L, 1); 406 | } 407 | *(int_list*)c_out = list_space; 408 | } 409 | 410 | luaA_conversion_to(int_list, luaA_to_int_list); 411 | 412 | luaA_function(print_int_list, void, int_list, int); 413 | ``` 414 | 415 | As you can probably see, automatic wrapping and type conversion becomes hard when memory management and pointers are involved. 416 | 417 | 418 | Headers 419 | ------- 420 | 421 | It isn't any fun writing out all the registration functions, so I've included a basic Lua script which will auto-generate LuaAutoC code for structs and functions from C header files. In general it works pretty well, but it is fairly basic, not a C parser, and won't cover all situations, so expect to have to do some cleaning up for complicated headers. 422 | 423 | ``` 424 | $ lua lautoc.lua ../Corange/include/assets/sound.h 425 | 426 | luaA_struct(sound); 427 | luaA_struct_member(sound, data, char*); 428 | luaA_struct_member(sound, length, int); 429 | 430 | luaA_function(wav_load_file, sound*, char*); 431 | luaA_function(sound_delete, void, sound*); 432 | ``` 433 | 434 | Internals 435 | --------- 436 | 437 | LuaAutoC works by storing meta-information about C types, structs, and functions in the Lua registry. 438 | 439 | This allows it to automatically do conversions at runtime. In my opinion this is a far better approach than compile-time wrapping such as is available from programs such as SWIG. Because all the type information is stored in the Lua registry this allows for the use reflection techniques to ensure you build a Lua API that really does match the concepts of your C program. In essence LuaAutoC lets you build a powerful and complex API on the C side of things. 440 | 441 | It also means that LuaAutoC is completely un-intrusive, and can be used without touching your original codebase. There is no marking it up or wrapping to be done. Finally, because it is a runtime system, it can be changed, adapted and extended by other developers. You can actually provide functions for developers to use that _generate_ new bindings for their functions, types, or structs, without them having to know a thing about Lua! 442 | 443 | 444 | FAQ 445 | --- 446 | 447 | * How do unions work? 448 | 449 | They work the same way as structs. All the `luaA_struct` functions should be fine to use on them. Like in C though, accessing them "incorrectly" in Lua will result in the raw data being interpreted differently. Lua AutoC doesn't do any clever checking for you. 450 | 451 | * Function Pointer Casts? 452 | 453 | LuaAutoC casts function pointers to `void*` so that they can be used in the Lua ecosystem. For this reason it may not work on a platform that disallows these sorts of casts. 454 | 455 | * Nested Functions? 456 | 457 | By standard LuaAutoC makes uses of nested functions. Almost all compilers support these, but if not LuaAutoC can still be used. Instead functions must be "declared" outside of the program, and then "registered" in the runtime. See `example_unnested.c` for a clear example. 458 | 459 | * Is LuaAutoC slow? 460 | 461 | The short answer is no. For most uses LuaAutoC has to lookup runtime information in the Lua registry, and for calling functions it has to duplicate some of the process involved in managing the stack, but for any normal codebase this overhead is minimal. If you are concerned about performance you can still wrap your functions manually, but perhaps if you are using a scripting language like Lua it won't be worth it anyway. 462 | 463 | * Is this just macro hacks? Can I really use it in production code? 464 | 465 | There are certainly some macro tricks going on, but the backbone code is very simple. The macros just save typing. I know that it has been used successfully in production in [darktable](https://github.com/darktable-org/darktable) and probably elsewhere. Even so, if you are worried send me an email and I'll explain the internals so that you can decide for yourself. I've also written a short blog post about it [here](http://theorangeduck.com/page/autoc-tools). 466 | 467 | 468 | -------------------------------------------------------------------------------- /examples/example_basic.c: -------------------------------------------------------------------------------- 1 | #include "../lautoc.h" 2 | 3 | float power(float val, int pow) { 4 | float x = 1.0; 5 | for(int i = 0; i < pow; i++) { 6 | x = x * val; 7 | } 8 | return x; 9 | } 10 | 11 | int main(int argc, char **argv) { 12 | 13 | lua_State* L = luaL_newstate(); 14 | luaA_open(L); 15 | 16 | luaA_function(L, power, float, float, int); 17 | 18 | lua_pushnumber(L, 4.2); 19 | lua_pushinteger(L, 3); 20 | luaA_call(L, power); 21 | 22 | printf("Result: %f\n", lua_tonumber(L, -1)); 23 | lua_pop(L, 1); 24 | 25 | luaA_close(L); 26 | lua_close(L); 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /examples/example_convert.c: -------------------------------------------------------------------------------- 1 | #include "../lautoc.h" 2 | 3 | typedef struct { 4 | int fst, snd; 5 | } pair; 6 | 7 | static int luaA_push_pair(lua_State* L, luaA_Type t, const void* c_in) { 8 | pair* p = (pair*)c_in; 9 | lua_pushinteger(L, p->fst); 10 | lua_pushinteger(L, p->snd); 11 | return 2; 12 | } 13 | 14 | static void luaA_to_pair(lua_State* L, luaA_Type t, void* c_out, int index) { 15 | pair* p = (pair*)c_out; 16 | p->snd = lua_tointeger(L, index); 17 | p->fst = lua_tointeger(L, index-1); 18 | } 19 | 20 | typedef struct { 21 | int id; 22 | int legs; 23 | float height; 24 | } table; 25 | 26 | int main(int argc, char **argv) { 27 | 28 | lua_State* L = luaL_newstate(); 29 | luaA_open(L); 30 | 31 | luaA_conversion(L, pair, luaA_push_pair, luaA_to_pair); 32 | 33 | pair p = {20, 10}; 34 | luaA_push(L, pair, &p); 35 | lua_pop(L, 2); 36 | 37 | luaA_struct(L, table); 38 | luaA_struct_member(L, table, id, int); 39 | luaA_struct_member(L, table, legs, int); 40 | luaA_struct_member(L, table, height, float); 41 | 42 | table t = {0, 4, 0.72}; 43 | 44 | luaA_push(L, table, &t); 45 | 46 | lua_getfield(L, -1, "legs"); 47 | printf("legs: %i\n", (int)lua_tointeger(L, -1)); 48 | lua_pop(L, 1); 49 | 50 | lua_getfield(L, -1, "height"); 51 | printf("height: %f\n", lua_tonumber(L, -1)); 52 | lua_pop(L, 1); 53 | 54 | lua_pop(L, 1); 55 | 56 | luaA_close(L); 57 | lua_close(L); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /examples/example_embed.c: -------------------------------------------------------------------------------- 1 | #include "../lautoc.h" 2 | 3 | typedef struct { 4 | char* name; 5 | int num_wings; 6 | } birdie; 7 | 8 | birdie test_birdie; 9 | 10 | birdie* get_instance_ptr(lua_State* L) { 11 | return &test_birdie; 12 | } 13 | 14 | int birdie_index(lua_State* L) { 15 | const char* membername = lua_tostring(L, -1); 16 | birdie* self = get_instance_ptr(L); 17 | return luaA_struct_push_member_name(L, birdie, membername, self); 18 | } 19 | 20 | int birdie_newindex(lua_State* L) { 21 | const char* membername = lua_tostring(L, -2); 22 | birdie* self = get_instance_ptr(L); 23 | luaA_struct_to_member_name(L, birdie, membername, self, -1); 24 | return 0; 25 | } 26 | 27 | int main(int argc, char **argv) { 28 | 29 | test_birdie.name = "MrFlingly"; 30 | test_birdie.num_wings = 2; 31 | 32 | lua_State* L = luaL_newstate(); 33 | luaL_openlibs(L); 34 | luaA_open(L); 35 | 36 | luaA_struct(L, birdie); 37 | luaA_struct_member(L, birdie, name, char*); 38 | luaA_struct_member(L, birdie, num_wings, int); 39 | 40 | lua_register(L, "birdie_index", birdie_index); 41 | lua_register(L, "birdie_newindex", birdie_newindex); 42 | 43 | luaL_dostring(L, "" 44 | "Birdie = {}\n" 45 | "setmetatable(Birdie, Birdie)\n" 46 | "function Birdie.__call()\n" 47 | " local self = {}\n" 48 | " setmetatable(self, Birdie)\n" 49 | " return self\n" 50 | "end\n" 51 | "Birdie.__index = birdie_index\n" 52 | "Birdie.__newindex = birdie_newindex\n" 53 | "\n" 54 | "bird = Birdie()\n" 55 | "print(bird.name)\n" 56 | "print(bird.num_wings)\n" 57 | "bird.num_wings = 3\n" 58 | "print(bird.num_wings)\n" 59 | "\n"); 60 | 61 | luaA_close(L); 62 | lua_close(L); 63 | 64 | return 0; 65 | 66 | } 67 | -------------------------------------------------------------------------------- /examples/example_enum.c: -------------------------------------------------------------------------------- 1 | #include "../lautoc.h" 2 | 3 | typedef enum { 4 | DIAMONDS, 5 | HEARTS, 6 | CLUBS, 7 | SPADES, 8 | INVALID = -1 9 | } cards; 10 | 11 | int main(int argc, char **argv) { 12 | 13 | lua_State* L = luaL_newstate(); 14 | 15 | luaA_open(L); 16 | 17 | luaA_enum(L, cards); 18 | luaA_enum_value(L, cards, DIAMONDS); 19 | luaA_enum_value(L, cards, HEARTS); 20 | luaA_enum_value(L, cards, CLUBS); 21 | luaA_enum_value(L, cards, SPADES); 22 | luaA_enum_value(L, cards, INVALID); 23 | 24 | cards cval = SPADES; 25 | const char* lval = "SPADES"; 26 | 27 | luaA_push(L, cards, &cval); 28 | printf("%i pushed as %s\n", cval, lua_tostring(L, -1)); 29 | lua_pop(L, 1); 30 | 31 | lua_pushstring(L, lval); 32 | luaA_to(L, cards, &cval, -1); 33 | printf("%s read back as %i\n", lval, cval); 34 | lua_pop(L, 1); 35 | 36 | luaA_close(L); 37 | lua_close(L); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /examples/example_func.c: -------------------------------------------------------------------------------- 1 | #include "../lautoc.h" 2 | 3 | int fib(int n) { 4 | if (n == 0) { return 1; } 5 | if (n == 1) { return 1; } 6 | return fib(n-1) + fib(n-2); 7 | } 8 | 9 | int main(int argc, char** argv) { 10 | 11 | /* Init Lua & LuaAutoC */ 12 | lua_State* L = luaL_newstate(); 13 | luaA_open(L); 14 | 15 | /* Register `fib` function */ 16 | luaA_function(L, fib, int, int); 17 | 18 | /* Push integer onto stack and call `fib` */ 19 | lua_pushinteger(L, 25); 20 | luaA_call(L, fib); 21 | 22 | /* Print result & pop */ 23 | printf("Result: %i\n", (int)lua_tointeger(L, -1)); 24 | lua_pop(L, 1); 25 | 26 | luaA_close(L); 27 | lua_close(L); 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /examples/example_mod.c: -------------------------------------------------------------------------------- 1 | #include "../lautoc.h" 2 | 3 | /* Hello Module Begin */ 4 | 5 | void hello_world(void) { 6 | puts("Hello World!"); 7 | } 8 | 9 | void hello_repeat(int times) { 10 | for (int i = 0; i < times; i++) { 11 | hello_world(); 12 | } 13 | } 14 | 15 | void hello_person(const char* person) { 16 | printf("Hello %s!\n", person); 17 | } 18 | 19 | int hello_subcount(const char* greeting) { 20 | int count = 0; 21 | const char *tmp = greeting; 22 | while((tmp = strstr(tmp, "hello"))) { 23 | count++; tmp++; 24 | } 25 | return count; 26 | } 27 | 28 | /* Hello Module End */ 29 | 30 | int C(lua_State* L) { 31 | return luaA_call_name(L, lua_tostring(L, 1)); 32 | } 33 | 34 | int main(int argc, char **argv) { 35 | 36 | lua_State* L = luaL_newstate(); 37 | 38 | luaA_open(L); 39 | luaA_function(L, hello_world, void); 40 | luaA_function(L, hello_repeat, void, int); 41 | luaA_function(L, hello_person, void, const char*); 42 | luaA_function(L, hello_subcount, int, const char*); 43 | 44 | lua_register(L, "C", C); 45 | 46 | luaL_dostring(L, 47 | "C('hello_world')\n" 48 | "C('hello_person', 'Daniel')\n" 49 | "C('hello_repeat', C('hello_subcount', 'hello hello'))\n" 50 | ); 51 | 52 | luaA_close(L); 53 | lua_close(L); 54 | 55 | return 0; 56 | } -------------------------------------------------------------------------------- /examples/example_struct.c: -------------------------------------------------------------------------------- 1 | #include "../lautoc.h" 2 | 3 | typedef struct { 4 | float x, y, z; 5 | } vec3; 6 | 7 | int main(int argc, char **argv) { 8 | 9 | lua_State* L = luaL_newstate(); 10 | 11 | luaA_open(L); 12 | luaA_struct(L, vec3); 13 | luaA_struct_member(L, vec3, x, float); 14 | luaA_struct_member(L, vec3, y, float); 15 | luaA_struct_member(L, vec3, z, float); 16 | 17 | vec3 pos = {1.0f, 2.11f, 3.16f}; 18 | 19 | luaA_struct_push_member(L, vec3, x, &pos); 20 | printf("x: %f\n", lua_tonumber(L, -1)); 21 | lua_pop(L, 1); 22 | 23 | lua_pushnumber(L, 0.0); 24 | luaA_struct_to_member(L, vec3, x, &pos, -1); 25 | lua_pop(L, 1); 26 | 27 | luaA_struct_push_member(L, vec3, x, &pos); 28 | printf("x: %f\n", lua_tonumber(L, -1)); 29 | lua_pop(L, 1); 30 | 31 | luaA_close(L); 32 | lua_close(L); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /examples/example_unnested.c: -------------------------------------------------------------------------------- 1 | #include "../lautoc.h" 2 | 3 | int fib(int n) { 4 | if (n == 0) { return 1; } 5 | if (n == 1) { return 1; } 6 | return fib(n-1) + fib(n-2); 7 | } 8 | 9 | luaA_function_declare(fib, int, int); 10 | 11 | int main(int argc, char** argv) { 12 | 13 | lua_State* L = luaL_newstate(); 14 | luaA_open(L); 15 | 16 | luaA_function_register(L, fib, int, int); 17 | 18 | lua_pushinteger(L, 25); 19 | luaA_call(L, fib); 20 | 21 | printf("Result: %i\n", (int)lua_tointeger(L, -1)); 22 | lua_pop(L, 1); 23 | 24 | luaA_close(L); 25 | lua_close(L); 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /lautoc.c: -------------------------------------------------------------------------------- 1 | #include "lautoc.h" 2 | 3 | void luaA_open(lua_State* L) { 4 | 5 | lua_pushinteger(L, 0); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_index"); 6 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids"); 7 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_names"); 8 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_sizes"); 9 | 10 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push"); 11 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to"); 12 | 13 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 14 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset"); 15 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums"); 16 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes"); 17 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values"); 18 | lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions"); 19 | 20 | lua_newuserdata(L, LUAA_RETURN_STACK_SIZE); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_stk"); 21 | lua_newuserdata(L, LUAA_ARGUMENT_STACK_SIZE); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_stk"); 22 | lua_pushinteger(L, 0); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr"); 23 | lua_pushinteger(L, 0); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_ptr"); 24 | 25 | // compiler does weird macro expansion with "bool" so no magic macro for you 26 | luaA_conversion_type(L, luaA_type_add(L,"bool",sizeof(bool)), luaA_push_bool, luaA_to_bool); 27 | luaA_conversion_type(L, luaA_type_add(L,"_Bool",sizeof(bool)), luaA_push_bool, luaA_to_bool); 28 | luaA_conversion(L, char, luaA_push_char, luaA_to_char); 29 | luaA_conversion(L, signed char, luaA_push_signed_char, luaA_to_signed_char); 30 | luaA_conversion(L, unsigned char, luaA_push_unsigned_char, luaA_to_unsigned_char); 31 | luaA_conversion(L, short, luaA_push_short, luaA_to_short); 32 | luaA_conversion(L, unsigned short, luaA_push_unsigned_short, luaA_to_unsigned_short); 33 | luaA_conversion(L, int, luaA_push_int, luaA_to_int); 34 | luaA_conversion(L, unsigned int, luaA_push_unsigned_int, luaA_to_unsigned_int); 35 | luaA_conversion(L, long, luaA_push_long, luaA_to_long); 36 | luaA_conversion(L, unsigned long, luaA_push_unsigned_long, luaA_to_unsigned_long); 37 | luaA_conversion(L, long long, luaA_push_long_long, luaA_to_long_long); 38 | luaA_conversion(L, unsigned long long, luaA_push_unsigned_long_long, luaA_to_unsigned_long_long); 39 | luaA_conversion(L, float, luaA_push_float, luaA_to_float); 40 | luaA_conversion(L, double, luaA_push_double, luaA_to_double); 41 | luaA_conversion(L, long double, luaA_push_long_double, luaA_to_long_double); 42 | 43 | luaA_conversion_push_type(L, luaA_type_add(L,"const bool",sizeof(bool)), luaA_push_bool); 44 | luaA_conversion_push_type(L, luaA_type_add(L,"const _Bool",sizeof(bool)), luaA_push_bool); 45 | luaA_conversion_push(L, const char, luaA_push_char); 46 | luaA_conversion_push(L, const signed char, luaA_push_signed_char); 47 | luaA_conversion_push(L, const unsigned char, luaA_push_unsigned_char); 48 | luaA_conversion_push(L, const short, luaA_push_short); 49 | luaA_conversion_push(L, const unsigned short, luaA_push_unsigned_short); 50 | luaA_conversion_push(L, const int, luaA_push_int); 51 | luaA_conversion_push(L, const unsigned int, luaA_push_unsigned_int); 52 | luaA_conversion_push(L, const long, luaA_push_long); 53 | luaA_conversion_push(L, const unsigned long, luaA_push_unsigned_long); 54 | luaA_conversion_push(L, const long long, luaA_push_long_long); 55 | luaA_conversion_push(L, const unsigned long long, luaA_push_unsigned_long_long); 56 | luaA_conversion_push(L, const float, luaA_push_float); 57 | luaA_conversion_push(L, const double, luaA_push_double); 58 | luaA_conversion_push(L, const long double, luaA_push_long_double); 59 | 60 | luaA_conversion(L, char*, luaA_push_char_ptr, luaA_to_char_ptr); 61 | luaA_conversion(L, const char*, luaA_push_const_char_ptr, luaA_to_const_char_ptr); 62 | luaA_conversion(L, void*, luaA_push_void_ptr, luaA_to_void_ptr); 63 | 64 | luaA_conversion_push(L, void, luaA_push_void); 65 | 66 | } 67 | 68 | void luaA_close(lua_State* L) { 69 | 70 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_index"); 71 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids"); 72 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_names"); 73 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_sizes"); 74 | 75 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push"); 76 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to"); 77 | 78 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 79 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset"); 80 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums"); 81 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes"); 82 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values"); 83 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions"); 84 | 85 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_stk"); 86 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_stk"); 87 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr"); 88 | lua_pushnil(L); lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_ptr"); 89 | 90 | } 91 | 92 | /* 93 | ** Types 94 | */ 95 | 96 | luaA_Type luaA_type_add(lua_State* L, const char* type, size_t size) { 97 | 98 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids"); 99 | lua_getfield(L, -1, type); 100 | 101 | if (lua_isnumber(L, -1)) { 102 | 103 | luaA_Type id = lua_tointeger(L, -1); 104 | lua_pop(L, 2); 105 | return id; 106 | 107 | } else { 108 | 109 | lua_pop(L, 2); 110 | 111 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_index"); 112 | 113 | luaA_Type id = lua_tointeger(L, -1); 114 | lua_pop(L, 1); 115 | id++; 116 | 117 | lua_pushinteger(L, id); 118 | lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_index"); 119 | 120 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids"); 121 | lua_pushinteger(L, id); 122 | lua_setfield(L, -2, type); 123 | lua_pop(L, 1); 124 | 125 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_names"); 126 | lua_pushinteger(L, id); 127 | lua_pushstring(L, type); 128 | lua_settable(L, -3); 129 | lua_pop(L, 1); 130 | 131 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_sizes"); 132 | lua_pushinteger(L, id); 133 | lua_pushinteger(L, size); 134 | lua_settable(L, -3); 135 | lua_pop(L, 1); 136 | 137 | return id; 138 | 139 | } 140 | 141 | } 142 | 143 | luaA_Type luaA_type_find(lua_State* L, const char* type) { 144 | 145 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_ids"); 146 | lua_getfield(L, -1, type); 147 | 148 | luaA_Type id = lua_isnil(L, -1) ? LUAA_INVALID_TYPE : lua_tointeger(L, -1); 149 | lua_pop(L, 2); 150 | 151 | return id; 152 | } 153 | 154 | const char* luaA_typename(lua_State* L, luaA_Type id) { 155 | 156 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_names"); 157 | lua_pushinteger(L, id); 158 | lua_gettable(L, -2); 159 | 160 | const char* type = lua_isnil(L, -1) ? "LUAA_INVALID_TYPE" : lua_tostring(L, -1); 161 | lua_pop(L, 2); 162 | 163 | return type; 164 | } 165 | 166 | size_t luaA_typesize(lua_State* L, luaA_Type id) { 167 | 168 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "type_sizes"); 169 | lua_pushinteger(L, id); 170 | lua_gettable(L, -2); 171 | 172 | size_t size = lua_isnil(L, -1) ? -1 : lua_tointeger(L, -1); 173 | lua_pop(L, 2); 174 | 175 | return size; 176 | } 177 | 178 | /* 179 | ** Stack 180 | */ 181 | 182 | int luaA_push_type(lua_State* L, luaA_Type type_id, const void* c_in) { 183 | 184 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push"); 185 | lua_pushinteger(L, type_id); 186 | lua_gettable(L, -2); 187 | 188 | if (!lua_isnil(L, -1)) { 189 | luaA_Pushfunc func = lua_touserdata(L, -1); 190 | lua_pop(L, 2); 191 | return func(L, type_id, c_in); 192 | } 193 | 194 | lua_pop(L, 2); 195 | 196 | if (luaA_struct_registered_type(L, type_id)) { 197 | return luaA_struct_push_type(L, type_id, c_in); 198 | } 199 | 200 | if (luaA_enum_registered_type(L, type_id)) { 201 | return luaA_enum_push_type(L, type_id, c_in); 202 | } 203 | 204 | lua_pushfstring(L, "luaA_push: conversion to Lua object from type '%s' not registered!", luaA_typename(L, type_id)); 205 | lua_error(L); 206 | return 0; 207 | } 208 | 209 | void luaA_to_type(lua_State* L, luaA_Type type_id, void* c_out, int index) { 210 | 211 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to"); 212 | lua_pushinteger(L, type_id); 213 | lua_gettable(L, -2); 214 | 215 | if (!lua_isnil(L, -1)) { 216 | luaA_Tofunc func = lua_touserdata(L, -1); 217 | lua_pop(L, 2); 218 | func(L, type_id, c_out, index); 219 | return; 220 | } 221 | 222 | lua_pop(L, 2); 223 | 224 | if (luaA_struct_registered_type(L, type_id)) { 225 | luaA_struct_to_type(L, type_id, c_out, index); 226 | return; 227 | } 228 | 229 | if (luaA_enum_registered_type(L, type_id)) { 230 | luaA_enum_to_type(L, type_id, c_out, index); 231 | return; 232 | } 233 | 234 | lua_pushfstring(L, "luaA_to: conversion from Lua object to type '%s' not registered!", luaA_typename(L, type_id)); 235 | lua_error(L); 236 | } 237 | 238 | void luaA_conversion_type(lua_State* L, luaA_Type type_id, luaA_Pushfunc push_func, luaA_Tofunc to_func) { 239 | luaA_conversion_push_type(L, type_id, push_func); 240 | luaA_conversion_to_type(L, type_id, to_func); 241 | } 242 | 243 | void luaA_conversion_push_type(lua_State* L, luaA_Type type_id, luaA_Pushfunc func) { 244 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push"); 245 | lua_pushinteger(L, type_id); 246 | lua_pushlightuserdata(L, func); 247 | lua_settable(L, -3); 248 | lua_pop(L, 1); 249 | } 250 | 251 | void luaA_conversion_to_type(lua_State* L, luaA_Type type_id, luaA_Tofunc func) { 252 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to"); 253 | lua_pushinteger(L, type_id); 254 | lua_pushlightuserdata(L, func); 255 | lua_settable(L, -3); 256 | lua_pop(L, 1); 257 | } 258 | 259 | int luaA_push_bool(lua_State* L, luaA_Type type_id, const void* c_in) { 260 | lua_pushboolean(L, *(bool*)c_in); 261 | return 1; 262 | } 263 | 264 | void luaA_to_bool(lua_State* L, luaA_Type type_id, void* c_out, int index) { 265 | *(bool*)c_out = lua_toboolean(L, index); 266 | } 267 | 268 | int luaA_push_char(lua_State* L, luaA_Type type_id, const void* c_in) { 269 | lua_pushinteger(L, *(char*)c_in); 270 | return 1; 271 | } 272 | 273 | void luaA_to_char(lua_State* L, luaA_Type type_id, void* c_out, int index) { 274 | *(char*)c_out = lua_tointeger(L, index); 275 | } 276 | 277 | int luaA_push_signed_char(lua_State* L, luaA_Type type_id, const void* c_in) { 278 | lua_pushinteger(L, *(signed char*)c_in); 279 | return 1; 280 | } 281 | 282 | void luaA_to_signed_char(lua_State* L, luaA_Type type_id, void* c_out, int index) { 283 | *(signed char*)c_out = lua_tointeger(L, index); 284 | } 285 | 286 | int luaA_push_unsigned_char(lua_State* L, luaA_Type type_id, const void* c_in) { 287 | lua_pushinteger(L, *(unsigned char*)c_in); 288 | return 1; 289 | } 290 | 291 | void luaA_to_unsigned_char(lua_State* L, luaA_Type type_id, void* c_out, int index) { 292 | *(unsigned char*)c_out = lua_tointeger(L, index); 293 | } 294 | 295 | int luaA_push_short(lua_State* L, luaA_Type type_id, const void* c_in) { 296 | lua_pushinteger(L, *(short*)c_in); 297 | return 1; 298 | } 299 | 300 | void luaA_to_short(lua_State* L, luaA_Type type_id, void* c_out, int index) { 301 | *(short*)c_out = lua_tointeger(L, index); 302 | } 303 | 304 | int luaA_push_unsigned_short(lua_State* L, luaA_Type type_id, const void* c_in) { 305 | lua_pushinteger(L, *(unsigned short*)c_in); 306 | return 1; 307 | } 308 | 309 | void luaA_to_unsigned_short(lua_State* L, luaA_Type type_id, void* c_out, int index) { 310 | *(unsigned short*)c_out = lua_tointeger(L, index); 311 | } 312 | 313 | int luaA_push_int(lua_State* L, luaA_Type type_id, const void* c_in) { 314 | lua_pushinteger(L, *(int*)c_in); 315 | return 1; 316 | } 317 | 318 | void luaA_to_int(lua_State* L, luaA_Type type_id, void* c_out, int index) { 319 | *(int*)c_out = lua_tointeger(L, index); 320 | } 321 | 322 | int luaA_push_unsigned_int(lua_State* L, luaA_Type type_id, const void* c_in) { 323 | lua_pushinteger(L, *(unsigned int*)c_in); 324 | return 1; 325 | } 326 | 327 | void luaA_to_unsigned_int(lua_State* L, luaA_Type type_id, void* c_out, int index) { 328 | *(unsigned int*)c_out = lua_tointeger(L, index); 329 | } 330 | 331 | int luaA_push_long(lua_State* L, luaA_Type type_id, const void* c_in) { 332 | lua_pushinteger(L, *(long*)c_in); 333 | return 1; 334 | } 335 | 336 | void luaA_to_long(lua_State* L, luaA_Type type_id, void* c_out, int index) { 337 | *(long*)c_out = lua_tointeger(L, index); 338 | } 339 | 340 | int luaA_push_unsigned_long(lua_State* L, luaA_Type type_id, const void* c_in) { 341 | lua_pushinteger(L, *(unsigned long*)c_in); 342 | return 1; 343 | } 344 | 345 | void luaA_to_unsigned_long(lua_State* L, luaA_Type type_id, void* c_out, int index) { 346 | *(unsigned long*)c_out = lua_tointeger(L, index); 347 | } 348 | 349 | int luaA_push_long_long(lua_State* L, luaA_Type type_id, const void* c_in) { 350 | lua_pushinteger(L, *(long long*)c_in); 351 | return 1; 352 | } 353 | 354 | void luaA_to_long_long(lua_State* L, luaA_Type type_id, void* c_out, int index) { 355 | *(long long*)c_out = lua_tointeger(L, index); 356 | } 357 | 358 | int luaA_push_unsigned_long_long(lua_State* L, luaA_Type type_id, const void* c_in) { 359 | lua_pushinteger(L, *(unsigned long long*)c_in); 360 | return 1; 361 | } 362 | 363 | void luaA_to_unsigned_long_long(lua_State* L, luaA_Type type_id, void* c_out, int index) { 364 | *(unsigned long long*)c_out = lua_tointeger(L, index); 365 | } 366 | 367 | int luaA_push_float(lua_State* L, luaA_Type type_id, const void* c_in) { 368 | lua_pushnumber(L, *(float*)c_in); 369 | return 1; 370 | } 371 | 372 | void luaA_to_float(lua_State* L, luaA_Type type_id, void* c_out, int index) { 373 | *(float*)c_out = lua_tonumber(L, index); 374 | } 375 | 376 | int luaA_push_double(lua_State* L, luaA_Type type_id, const void* c_in) { 377 | lua_pushnumber(L, *(double*)c_in); 378 | return 1; 379 | } 380 | 381 | void luaA_to_double(lua_State* L, luaA_Type type_id, void* c_out, int index) { 382 | *(double*)c_out = lua_tonumber(L, index); 383 | } 384 | 385 | int luaA_push_long_double(lua_State* L, luaA_Type type_id, const void* c_in) { 386 | lua_pushnumber(L, *(long double*)c_in); 387 | return 1; 388 | } 389 | 390 | void luaA_to_long_double(lua_State* L, luaA_Type type_id, void* c_out, int index) { 391 | *(long double*)c_out = lua_tonumber(L, index); 392 | } 393 | 394 | int luaA_push_char_ptr(lua_State* L, luaA_Type type_id, const void* c_in) { 395 | lua_pushstring(L, *(char**)c_in); 396 | return 1; 397 | } 398 | 399 | void luaA_to_char_ptr(lua_State* L, luaA_Type type_id, void* c_out, int index) { 400 | *(char**)c_out = (char*)lua_tostring(L, index); 401 | } 402 | 403 | int luaA_push_const_char_ptr(lua_State* L, luaA_Type type_id, const void* c_in) { 404 | lua_pushstring(L, *(const char**)c_in); 405 | return 1; 406 | } 407 | 408 | void luaA_to_const_char_ptr(lua_State* L, luaA_Type type_id, void* c_out, int index) { 409 | *(const char**)c_out = lua_tostring(L, index); 410 | } 411 | 412 | int luaA_push_void_ptr(lua_State* L, luaA_Type type_id, const void* c_in) { 413 | lua_pushlightuserdata(L, *(void**)c_in); 414 | return 1; 415 | } 416 | 417 | void luaA_to_void_ptr(lua_State* L, luaA_Type type_id, void* c_out, int index) { 418 | *(void**)c_out = (void*)lua_touserdata(L, index); 419 | } 420 | 421 | int luaA_push_void(lua_State* L, luaA_Type type_id, const void* c_in) { 422 | lua_pushnil(L); 423 | return 1; 424 | } 425 | 426 | bool luaA_conversion_registered_type(lua_State* L, luaA_Type type_id) { 427 | return (luaA_conversion_push_registered_type(L, type_id) 428 | && luaA_conversion_to_registered_type(L, type_id)); 429 | } 430 | 431 | bool luaA_conversion_push_registered_type(lua_State* L, luaA_Type type_id) { 432 | 433 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_push"); 434 | lua_pushinteger(L, type_id); 435 | lua_gettable(L, -2); 436 | 437 | bool reg = !lua_isnil(L, -1); 438 | lua_pop(L, 2); 439 | 440 | return reg; 441 | } 442 | 443 | bool luaA_conversion_to_registered_type(lua_State* L, luaA_Type type_id) { 444 | 445 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "stack_to"); 446 | lua_pushinteger(L, type_id); 447 | lua_gettable(L, -2); 448 | 449 | bool reg = !lua_isnil(L, -1); 450 | lua_pop(L, 2); 451 | 452 | return reg; 453 | } 454 | 455 | /* 456 | ** Structs 457 | */ 458 | 459 | int luaA_struct_push_member_offset_type(lua_State* L, luaA_Type type, size_t offset, const void* c_in) { 460 | 461 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset"); 462 | lua_pushinteger(L, type); 463 | lua_gettable(L, -2); 464 | 465 | if (!lua_isnil(L, -1)) { 466 | 467 | lua_pushinteger(L, offset); 468 | lua_gettable(L, -2); 469 | 470 | if (!lua_isnil(L, -1)) { 471 | lua_getfield(L, -1, "type"); 472 | luaA_Type stype = lua_tointeger(L, -1); 473 | lua_pop(L, 4); 474 | return luaA_push_type(L, stype, c_in + offset); 475 | } 476 | 477 | lua_pop(L, 3); 478 | lua_pushfstring(L, "luaA_struct_push_member: Member offset '%d' not registered for struct '%s'!", offset, luaA_typename(L, type)); 479 | lua_error(L); 480 | 481 | } 482 | 483 | lua_pop(L, 2); 484 | lua_pushfstring(L, "luaA_struct_push_member: Struct '%s' not registered!", luaA_typename(L, type)); 485 | lua_error(L); 486 | return 0; 487 | 488 | } 489 | 490 | int luaA_struct_push_member_name_type(lua_State* L, luaA_Type type, const char* member, const void* c_in) { 491 | 492 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 493 | lua_pushinteger(L, type); 494 | lua_gettable(L, -2); 495 | 496 | if (!lua_isnil(L, -1)) { 497 | 498 | lua_getfield(L, -1, member); 499 | 500 | if (!lua_isnil(L, -1)) { 501 | lua_getfield(L, -1, "type"); 502 | luaA_Type stype = lua_tointeger(L, -1); 503 | lua_pop(L, 1); 504 | lua_getfield(L, -1, "offset"); 505 | size_t offset = lua_tointeger(L, -1); 506 | lua_pop(L, 4); 507 | return luaA_push_type(L, stype, c_in + offset); 508 | } 509 | 510 | lua_pop(L, 3); 511 | lua_pushfstring(L, "luaA_struct_push_member: Member name '%s' not registered for struct '%s'!", member, luaA_typename(L, type)); 512 | lua_error(L); 513 | 514 | } 515 | 516 | lua_pop(L, 2); 517 | lua_pushfstring(L, "luaA_struct_push_member: Struct '%s' not registered!", luaA_typename(L, type)); 518 | lua_error(L); 519 | return 0; 520 | } 521 | 522 | void luaA_struct_to_member_offset_type(lua_State* L, luaA_Type type, size_t offset, void* c_out, int index) { 523 | 524 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset"); 525 | lua_pushinteger(L, type); 526 | lua_gettable(L, -2); 527 | 528 | if (!lua_isnil(L, -1)) { 529 | 530 | lua_pushinteger(L, offset); 531 | lua_gettable(L, -2); 532 | 533 | if (!lua_isnil(L, -1)) { 534 | lua_getfield(L, -1, "type"); 535 | luaA_Type stype = lua_tointeger(L, -1); 536 | lua_pop(L, 4); 537 | luaA_to_type(L, stype, c_out + offset, index); 538 | return; 539 | } 540 | 541 | lua_pop(L, 3); 542 | lua_pushfstring(L, "luaA_struct_to_member: Member offset '%d' not registered for struct '%s'!", offset, luaA_typename(L, type)); 543 | lua_error(L); 544 | 545 | } 546 | 547 | lua_pop(L, 2); 548 | lua_pushfstring(L, "luaA_struct_to_member: Struct '%s' not registered!", luaA_typename(L, type)); 549 | lua_error(L); 550 | 551 | } 552 | 553 | void luaA_struct_to_member_name_type(lua_State* L, luaA_Type type, const char* member, void* c_out, int index) { 554 | 555 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 556 | lua_pushinteger(L, type); 557 | lua_gettable(L, -2); 558 | 559 | if (!lua_isnil(L, -1)) { 560 | 561 | lua_pushstring(L, member); 562 | lua_gettable(L, -2); 563 | 564 | if (!lua_isnil(L, -1)) { 565 | lua_getfield(L, -1, "type"); 566 | luaA_Type stype = lua_tointeger(L, -1); 567 | lua_pop(L, 1); 568 | lua_getfield(L, -1, "offset"); 569 | size_t offset = lua_tointeger(L, -1); 570 | lua_pop(L, 4); 571 | luaA_to_type(L, stype, c_out + offset, index); 572 | return; 573 | } 574 | 575 | lua_pop(L, 3); 576 | lua_pushfstring(L, "luaA_struct_to_member: Member name '%s' not registered for struct '%s'!", member, luaA_typename(L, type)); 577 | lua_error(L); 578 | 579 | } 580 | 581 | lua_pop(L, 2); 582 | lua_pushfstring(L, "luaA_struct_to_member: Struct '%s' not registered!", luaA_typename(L, type)); 583 | lua_error(L); 584 | 585 | } 586 | 587 | bool luaA_struct_has_member_offset_type(lua_State* L, luaA_Type type, size_t offset) { 588 | 589 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset"); 590 | lua_pushinteger(L, type); 591 | lua_gettable(L, -2); 592 | 593 | if (!lua_isnil(L, -1)) { 594 | 595 | lua_pushinteger(L, offset); 596 | lua_gettable(L, -2); 597 | 598 | if (!lua_isnil(L, -1)) { 599 | lua_pop(L, 3); 600 | return true; 601 | } 602 | 603 | lua_pop(L, 3); 604 | return false; 605 | 606 | } 607 | 608 | lua_pop(L, 2); 609 | lua_pushfstring(L, "luaA_struct_has_member: Struct '%s' not registered!", luaA_typename(L, type)); 610 | lua_error(L); 611 | return false; 612 | 613 | } 614 | 615 | bool luaA_struct_has_member_name_type(lua_State* L, luaA_Type type, const char* member) { 616 | 617 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 618 | lua_pushinteger(L, type); 619 | lua_gettable(L, -2); 620 | 621 | if (!lua_isnil(L, -1)) { 622 | 623 | lua_pushstring(L, member); 624 | lua_gettable(L, -2); 625 | 626 | if (!lua_isnil(L, -1)) { 627 | lua_pop(L, 3); 628 | return true; 629 | } 630 | 631 | lua_pop(L, 3); 632 | return false; 633 | 634 | } 635 | 636 | lua_pop(L, 2); 637 | lua_pushfstring(L, "luaA_struct_has_member: Struct '%s' not registered!", luaA_typename(L, type)); 638 | lua_error(L); 639 | return false; 640 | 641 | } 642 | 643 | luaA_Type luaA_struct_typeof_member_offset_type(lua_State* L, luaA_Type type, size_t offset) { 644 | 645 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset"); 646 | lua_pushinteger(L, type); 647 | lua_gettable(L, -2); 648 | 649 | if (!lua_isnil(L, -1)) { 650 | 651 | lua_pushinteger(L, offset); 652 | lua_gettable(L, -2); 653 | 654 | if (!lua_isnil(L, -1)) { 655 | lua_getfield(L, -1, "type"); 656 | luaA_Type stype = lua_tointeger(L, -1); 657 | lua_pop(L, 4); 658 | return stype; 659 | } 660 | 661 | lua_pop(L, 3); 662 | lua_pushfstring(L, "luaA_struct_typeof_member: Member offset '%d' not registered for struct '%s'!", offset, luaA_typename(L, type)); 663 | lua_error(L); 664 | 665 | } 666 | 667 | lua_pop(L, 2); 668 | lua_pushfstring(L, "luaA_struct_typeof_member: Struct '%s' not registered!", luaA_typename(L, type)); 669 | lua_error(L); 670 | return 0; 671 | 672 | } 673 | 674 | luaA_Type luaA_struct_typeof_member_name_type(lua_State* L, luaA_Type type, const char* member) { 675 | 676 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 677 | lua_pushinteger(L, type); 678 | lua_gettable(L, -2); 679 | 680 | if (!lua_isnil(L, -1)) { 681 | 682 | lua_pushstring(L, member); 683 | lua_gettable(L, -2); 684 | 685 | if (!lua_isnil(L, -1)) { 686 | lua_getfield(L, -1, "type"); 687 | luaA_Type type = lua_tointeger(L, -1); 688 | lua_pop(L, 4); 689 | return type; 690 | } 691 | 692 | lua_pop(L, 3); 693 | lua_pushfstring(L, "luaA_struct_typeof_member: Member name '%s' not registered for struct '%s'!", member, luaA_typename(L, type)); 694 | lua_error(L); 695 | 696 | } 697 | 698 | lua_pop(L, 2); 699 | lua_pushfstring(L, "luaA_struct_typeof_member: Struct '%s' not registered!", luaA_typename(L, type)); 700 | lua_error(L); 701 | return 0; 702 | 703 | } 704 | 705 | void luaA_struct_type(lua_State* L, luaA_Type type) { 706 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 707 | lua_pushinteger(L, type); 708 | lua_newtable(L); 709 | lua_settable(L, -3); 710 | lua_pop(L, 1); 711 | 712 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset"); 713 | lua_pushinteger(L, type); 714 | lua_newtable(L); 715 | lua_settable(L, -3); 716 | lua_pop(L, 1); 717 | } 718 | 719 | void luaA_struct_member_type(lua_State* L, luaA_Type type, const char* member, luaA_Type mtype, size_t offset) { 720 | 721 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 722 | lua_pushinteger(L, type); 723 | lua_gettable(L, -2); 724 | 725 | if (!lua_isnil(L, -1)) { 726 | 727 | lua_newtable(L); 728 | 729 | lua_pushinteger(L, mtype); lua_setfield(L, -2, "type"); 730 | lua_pushinteger(L, offset); lua_setfield(L, -2, "offset"); 731 | lua_pushstring(L, member); lua_setfield(L, -2, "name"); 732 | 733 | lua_setfield(L, -2, member); 734 | 735 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs_offset"); 736 | lua_pushinteger(L, type); 737 | lua_gettable(L, -2); 738 | 739 | lua_pushinteger(L, offset); 740 | lua_getfield(L, -4, member); 741 | lua_settable(L, -3); 742 | lua_pop(L, 4); 743 | return; 744 | } 745 | 746 | lua_pop(L, 2); 747 | lua_pushfstring(L, "luaA_struct_member: Struct '%s' not registered!", luaA_typename(L, type)); 748 | lua_error(L); 749 | } 750 | 751 | bool luaA_struct_registered_type(lua_State* L, luaA_Type type) { 752 | 753 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 754 | lua_pushinteger(L, type); 755 | lua_gettable(L, -2); 756 | 757 | bool reg = !lua_isnil(L, -1); 758 | lua_pop(L, 2); 759 | 760 | return reg; 761 | } 762 | 763 | int luaA_struct_push_type(lua_State* L, luaA_Type type, const void* c_in) { 764 | 765 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 766 | lua_pushinteger(L, type); 767 | lua_gettable(L, -2); 768 | 769 | if (!lua_isnil(L, -1)) { 770 | lua_remove(L, -2); 771 | lua_newtable(L); 772 | 773 | lua_pushnil(L); 774 | while (lua_next(L, -3)) { 775 | 776 | if (lua_type(L, -2) == LUA_TSTRING) { 777 | lua_getfield(L, -1, "name"); 778 | const char* name = lua_tostring(L, -1); 779 | lua_pop(L, 1); 780 | int num = luaA_struct_push_member_name_type(L, type, name, c_in); 781 | if (num > 1) { 782 | lua_pop(L, 5); 783 | lua_pushfstring(L, "luaA_struct_push: Conversion pushed %d values to stack," 784 | " don't know how to include in struct!", num); 785 | lua_error(L); 786 | } 787 | lua_remove(L, -2); 788 | lua_pushvalue(L, -2); 789 | lua_insert(L, -2); 790 | lua_settable(L, -4); 791 | } else { 792 | lua_pop(L, 1); 793 | } 794 | 795 | } 796 | 797 | lua_remove(L, -2); 798 | return 1; 799 | } 800 | 801 | lua_pop(L, 2); 802 | lua_pushfstring(L, "lua_struct_push: Struct '%s' not registered!", luaA_typename(L, type)); 803 | lua_error(L); 804 | return 0; 805 | } 806 | 807 | void luaA_struct_to_type(lua_State* L, luaA_Type type, void* c_out, int index) { 808 | 809 | lua_pushnil(L); 810 | while (lua_next(L, index-1)) { 811 | 812 | if (lua_type(L, -2) == LUA_TSTRING) { 813 | luaA_struct_to_member_name_type(L, type, lua_tostring(L, -2), c_out, -1); 814 | } 815 | 816 | lua_pop(L, 1); 817 | } 818 | 819 | } 820 | 821 | const char* luaA_struct_next_member_name_type(lua_State* L, luaA_Type type, const char* member) { 822 | 823 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "structs"); 824 | lua_pushinteger(L, type); 825 | lua_gettable(L, -2); 826 | 827 | if(!lua_isnil(L,-1)) { 828 | 829 | if(!member) { 830 | lua_pushnil(L); 831 | } else { 832 | lua_pushstring(L,member); 833 | } 834 | if(!lua_next(L,-2)) { 835 | lua_pop(L,2); 836 | return LUAA_INVALID_MEMBER_NAME; 837 | } 838 | const char* result = lua_tostring(L,-2); 839 | lua_pop(L,4); 840 | return result; 841 | } 842 | 843 | lua_pop(L, 2); 844 | lua_pushfstring(L, "luaA_struct_next_member: Struct '%s' not registered!", luaA_typename(L, type)); 845 | lua_error(L); 846 | return NULL; 847 | } 848 | 849 | /* 850 | ** Enums 851 | */ 852 | 853 | int luaA_enum_push_type(lua_State *L, luaA_Type type, const void* value) { 854 | 855 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values"); 856 | lua_pushinteger(L, type); 857 | lua_gettable(L, -2); 858 | 859 | if (!lua_isnil(L, -1)) { 860 | 861 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes"); 862 | lua_pushinteger(L, type); 863 | lua_gettable(L, -2); 864 | size_t size = lua_tointeger(L, -1); 865 | lua_pop(L, 2); 866 | 867 | lua_Integer lvalue =0; 868 | memcpy(&lvalue, value, size); 869 | 870 | lua_pushinteger(L, lvalue); 871 | lua_gettable(L, -2); 872 | 873 | if (!lua_isnil(L, -1)) { 874 | lua_getfield(L, -1, "name"); 875 | lua_remove(L, -2); 876 | lua_remove(L, -2); 877 | lua_remove(L, -2); 878 | return 1; 879 | } 880 | 881 | lua_pop(L, 3); 882 | lua_pushfstring(L, "luaA_enum_push: Enum '%s' value %d not registered!", luaA_typename(L, type), lvalue); 883 | lua_error(L); 884 | return 0; 885 | } 886 | 887 | lua_pop(L, 2); 888 | lua_pushfstring(L, "luaA_enum_push: Enum '%s' not registered!", luaA_typename(L, type)); 889 | lua_error(L); 890 | return 0; 891 | 892 | } 893 | 894 | void luaA_enum_to_type(lua_State* L, luaA_Type type, void* c_out, int index) { 895 | 896 | const char* name = lua_tostring(L, index); 897 | 898 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums"); 899 | lua_pushinteger(L, type); 900 | lua_gettable(L, -2); 901 | 902 | if (!lua_isnil(L, -1)) { 903 | 904 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes"); 905 | lua_pushinteger(L, type); 906 | lua_gettable(L, -2); 907 | size_t size = lua_tointeger(L, -1); 908 | lua_pop(L, 2); 909 | 910 | lua_pushstring(L, name); 911 | lua_gettable(L, -2); 912 | 913 | if (!lua_isnil(L, -1)) { 914 | lua_getfield(L, -1, "value"); 915 | lua_Integer value = lua_tointeger(L, -1); 916 | lua_pop(L, 4); 917 | memcpy(c_out, &value, size); 918 | return; 919 | } 920 | 921 | lua_pop(L, 3); 922 | lua_pushfstring(L, "luaA_enum_to: Enum '%s' field '%s' not registered!", luaA_typename(L, type), name); 923 | lua_error(L); 924 | return; 925 | } 926 | 927 | lua_pop(L, 3); 928 | lua_pushfstring(L, "luaA_enum_to: Enum '%s' not registered!", luaA_typename(L, type)); 929 | lua_error(L); 930 | return; 931 | } 932 | 933 | bool luaA_enum_has_value_type(lua_State* L, luaA_Type type, const void* value) { 934 | 935 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values"); 936 | lua_pushinteger(L, type); 937 | lua_gettable(L, -2); 938 | 939 | if (!lua_isnil(L, -1)) { 940 | 941 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes"); 942 | lua_pushinteger(L, type); 943 | lua_gettable(L, -2); 944 | size_t size = lua_tointeger(L, -1); 945 | lua_pop(L, 2); 946 | 947 | lua_Integer lvalue = 0; 948 | memcpy(&lvalue, value, size); 949 | 950 | lua_pushinteger(L, lvalue); 951 | lua_gettable(L, -2); 952 | 953 | if (lua_isnil(L, -1)) { 954 | lua_pop(L, 3); 955 | return false; 956 | } else { 957 | lua_pop(L, 3); 958 | return true; 959 | } 960 | 961 | } 962 | 963 | lua_pop(L, 2); 964 | lua_pushfstring(L, "luaA_enum_has_value: Enum '%s' not registered!", luaA_typename(L, type)); 965 | lua_error(L); 966 | return false; 967 | } 968 | 969 | bool luaA_enum_has_name_type(lua_State* L, luaA_Type type, const char* name) { 970 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums"); 971 | lua_pushinteger(L, type); 972 | lua_gettable(L, -2); 973 | 974 | if (!lua_isnil(L, -1)) { 975 | 976 | lua_getfield(L, -1, name); 977 | 978 | if (lua_isnil(L, -1)) { 979 | lua_pop(L, 3); 980 | return false; 981 | } else { 982 | lua_pop(L, 3); 983 | return true; 984 | } 985 | 986 | } 987 | 988 | lua_pop(L, 2); 989 | lua_pushfstring(L, "luaA_enum_has_name: Enum '%s' not registered!", luaA_typename(L, type)); 990 | lua_error(L); 991 | return false; 992 | } 993 | 994 | void luaA_enum_type(lua_State *L, luaA_Type type, size_t size) { 995 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums"); 996 | lua_pushinteger(L, type); 997 | lua_newtable(L); 998 | lua_settable(L, -3); 999 | lua_pop(L, 1); 1000 | 1001 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values"); 1002 | lua_pushinteger(L, type); 1003 | lua_newtable(L); 1004 | lua_settable(L, -3); 1005 | lua_pop(L, 1); 1006 | 1007 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes"); 1008 | lua_pushinteger(L, type); 1009 | lua_pushinteger(L, size); 1010 | lua_settable(L, -3); 1011 | lua_pop(L, 1); 1012 | } 1013 | 1014 | void luaA_enum_value_type(lua_State *L, luaA_Type type, const void* value, const char* name) { 1015 | 1016 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums"); 1017 | lua_pushinteger(L, type); 1018 | lua_gettable(L, -2); 1019 | 1020 | if (!lua_isnil(L, -1)) { 1021 | 1022 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_sizes"); 1023 | lua_pushinteger(L, type); 1024 | lua_gettable(L, -2); 1025 | size_t size = lua_tointeger(L, -1); 1026 | lua_pop(L, 2); 1027 | 1028 | lua_newtable(L); 1029 | 1030 | lua_Integer lvalue=0; 1031 | memcpy(&lvalue, value, size); 1032 | 1033 | lua_pushinteger(L, lvalue); 1034 | lua_setfield(L, -2, "value"); 1035 | 1036 | lua_pushstring(L, name); 1037 | lua_setfield(L, -2, "name"); 1038 | 1039 | lua_setfield(L, -2, name); 1040 | 1041 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums_values"); 1042 | lua_pushinteger(L, type); 1043 | lua_gettable(L, -2); 1044 | lua_pushinteger(L, lvalue); 1045 | lua_getfield(L, -4, name); 1046 | lua_settable(L, -3); 1047 | 1048 | lua_pop(L, 4); 1049 | return; 1050 | 1051 | } 1052 | 1053 | lua_pop(L, 2); 1054 | lua_pushfstring(L, "luaA_enum_value: Enum '%s' not registered!", luaA_typename(L, type)); 1055 | lua_error(L); 1056 | } 1057 | 1058 | bool luaA_enum_registered_type(lua_State *L, luaA_Type type){ 1059 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums"); 1060 | lua_pushinteger(L, type); 1061 | lua_gettable(L, -2); 1062 | bool reg = !lua_isnil(L, -1); 1063 | lua_pop(L, 2); 1064 | return reg; 1065 | } 1066 | 1067 | const char* luaA_enum_next_value_name_type(lua_State* L, luaA_Type type, const char* member) { 1068 | 1069 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "enums"); 1070 | lua_pushinteger(L, type); 1071 | lua_gettable(L, -2); 1072 | 1073 | if(!lua_isnil(L,-1)) { 1074 | 1075 | if(!member) { 1076 | lua_pushnil(L); 1077 | } else { 1078 | lua_pushstring(L,member); 1079 | } 1080 | if(!lua_next(L,-2)) { 1081 | lua_pop(L,2); 1082 | return LUAA_INVALID_MEMBER_NAME; 1083 | } 1084 | const char* result = lua_tostring(L,-2); 1085 | lua_pop(L,4); 1086 | return result; 1087 | } 1088 | 1089 | lua_pop(L, 2); 1090 | lua_pushfstring(L, "luaA_enum_next_enum_name_type: Enum '%s' not registered!", luaA_typename(L, type)); 1091 | lua_error(L); 1092 | return NULL; 1093 | } 1094 | 1095 | /* 1096 | ** Functions 1097 | */ 1098 | 1099 | static int luaA_call_entry(lua_State* L) { 1100 | 1101 | /* Get return size */ 1102 | 1103 | lua_getfield(L, -1, "ret_type"); 1104 | luaA_Type ret_type = lua_tointeger(L, -1); 1105 | lua_pop(L, 1); 1106 | 1107 | size_t ret_size = luaA_typesize(L, ret_type); 1108 | 1109 | /* Get total arguments sizes */ 1110 | 1111 | lua_getfield(L, -1, "arg_types"); 1112 | 1113 | size_t arg_size = 0; 1114 | size_t arg_num = lua_rawlen(L, -1); 1115 | 1116 | if (lua_gettop(L) < arg_num+2) { 1117 | lua_pop(L, 1); 1118 | lua_pushfstring(L, "luaA_call: Too few arguments to function!"); 1119 | lua_error(L); 1120 | return 0; 1121 | } 1122 | 1123 | for (int i = 0; i < arg_num; i++) { 1124 | lua_pushinteger(L, i+1); 1125 | lua_gettable(L, -2); 1126 | luaA_Type arg_type = lua_tointeger(L, -1); 1127 | lua_pop(L, 1); 1128 | arg_size += luaA_typesize(L, arg_type); 1129 | } 1130 | 1131 | lua_pop(L, 1); 1132 | 1133 | /* Test to see if using heap */ 1134 | 1135 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_stk"); 1136 | void* ret_stack = lua_touserdata(L, -1); 1137 | lua_pop(L, 1); 1138 | 1139 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_stk"); 1140 | void* arg_stack = lua_touserdata(L, -1); 1141 | lua_pop(L, 1); 1142 | 1143 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr"); 1144 | lua_Integer ret_ptr = lua_tointeger(L, -1); 1145 | lua_pop(L, 1); 1146 | 1147 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_ptr"); 1148 | lua_Integer arg_ptr = lua_tointeger(L, -1); 1149 | lua_pop(L, 1); 1150 | 1151 | void* ret_data = ret_stack + ret_ptr; 1152 | void* arg_data = arg_stack + arg_ptr; 1153 | 1154 | /* If fixed allocation exhausted use heap instead */ 1155 | 1156 | bool ret_heap = false; 1157 | bool arg_heap = false; 1158 | 1159 | if (ret_ptr + ret_size > LUAA_RETURN_STACK_SIZE) { 1160 | ret_heap = true; 1161 | ret_data = malloc(ret_size); 1162 | if (ret_data == NULL) { 1163 | lua_pushfstring(L, "luaA_call: Out of memory!"); 1164 | lua_error(L); 1165 | return 0; 1166 | } 1167 | } 1168 | 1169 | if (arg_ptr + arg_size > LUAA_ARGUMENT_STACK_SIZE) { 1170 | arg_heap = true; 1171 | arg_data = malloc(arg_size); 1172 | if (arg_data == NULL) { 1173 | if (ret_heap) { 1174 | free(ret_data); 1175 | } 1176 | lua_pushfstring(L, "luaA_call: Out of memory!"); 1177 | lua_error(L); 1178 | return 0; 1179 | } 1180 | } 1181 | 1182 | /* If not using heap update stack pointers */ 1183 | 1184 | if (!ret_heap) { 1185 | lua_pushinteger(L, ret_ptr + ret_size); 1186 | lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr"); 1187 | } 1188 | 1189 | if (!arg_heap) { 1190 | lua_pushinteger(L, arg_ptr + arg_size); 1191 | lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_arg_ptr"); 1192 | } 1193 | 1194 | /* Pop args and place in memory */ 1195 | 1196 | lua_getfield(L, -1, "arg_types"); 1197 | 1198 | void* arg_pos = arg_data; 1199 | for (int i = 0; i < arg_num; i++) { 1200 | lua_pushinteger(L, i+1); 1201 | lua_gettable(L, -2); 1202 | luaA_Type arg_type = lua_tointeger(L, -1); 1203 | lua_pop(L, 1); 1204 | luaA_to_type(L, arg_type, arg_pos, -arg_num+i-2); 1205 | arg_pos += luaA_typesize(L, arg_type); 1206 | } 1207 | 1208 | lua_pop(L, 1); 1209 | 1210 | /* Pop arguments from stack */ 1211 | 1212 | for (int i = 0; i < arg_num; i++) { 1213 | lua_remove(L, -2); 1214 | } 1215 | 1216 | /* Get Function Pointer and Call */ 1217 | 1218 | lua_getfield(L, -1, "auto_func"); 1219 | luaA_Func auto_func = lua_touserdata(L, -1); 1220 | lua_pop(L, 2); 1221 | 1222 | auto_func(ret_data, arg_data); 1223 | 1224 | int count = luaA_push_type(L, ret_type, ret_data); 1225 | 1226 | /* Either free heap data or reduce stack pointers */ 1227 | 1228 | if (!ret_heap) { 1229 | lua_pushinteger(L, ret_ptr); 1230 | lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "call_ret_ptr"); 1231 | } else { 1232 | free(ret_data); 1233 | } 1234 | 1235 | if (!arg_heap) { 1236 | lua_pushinteger(L, arg_ptr); 1237 | lua_setfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "argument_ptr"); 1238 | } else { 1239 | free(arg_data); 1240 | } 1241 | 1242 | return count; 1243 | } 1244 | 1245 | int luaA_call(lua_State* L, void* func_ptr) { 1246 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions"); 1247 | lua_pushlightuserdata(L, func_ptr); 1248 | lua_gettable(L, -2); 1249 | lua_remove(L, -2); 1250 | 1251 | if (!lua_isnil(L, -1)) { return luaA_call_entry(L); } 1252 | 1253 | lua_pop(L, 1); 1254 | lua_pushfstring(L, "luaA_call: Function with address '%p' is not registered!", func_ptr); 1255 | lua_error(L); 1256 | return 0; 1257 | } 1258 | 1259 | int luaA_call_name(lua_State* L, const char* func_name) { 1260 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions"); 1261 | lua_pushstring(L, func_name); 1262 | lua_gettable(L, -2); 1263 | lua_remove(L, -2); 1264 | 1265 | if (!lua_isnil(L, -1)) { return luaA_call_entry(L); } 1266 | 1267 | lua_pop(L, 1); 1268 | lua_pushfstring(L, "luaA_call_name: Function '%s' is not registered!", func_name); 1269 | lua_error(L); 1270 | return 0; 1271 | } 1272 | 1273 | void luaA_function_register_type(lua_State* L, void* src_func, luaA_Func auto_func, const char* name, luaA_Type ret_t, int num_args, ...) { 1274 | 1275 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions"); 1276 | lua_pushstring(L, name); 1277 | 1278 | lua_newtable(L); 1279 | 1280 | lua_pushlightuserdata(L, src_func); lua_setfield(L, -2, "src_func"); 1281 | lua_pushlightuserdata(L, auto_func); lua_setfield(L, -2, "auto_func"); 1282 | 1283 | lua_pushinteger(L, ret_t); 1284 | lua_setfield(L, -2, "ret_type"); 1285 | 1286 | lua_pushstring(L, "arg_types"); 1287 | lua_newtable(L); 1288 | 1289 | va_list va; 1290 | va_start(va, num_args); 1291 | for (int i = 0; i < num_args; i++) { 1292 | lua_pushinteger(L, i+1); 1293 | lua_pushinteger(L, va_arg(va, luaA_Type)); 1294 | lua_settable(L, -3); 1295 | } 1296 | va_end(va); 1297 | 1298 | lua_settable(L, -3); 1299 | lua_settable(L, -3); 1300 | lua_pop(L, 1); 1301 | 1302 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions"); 1303 | lua_pushlightuserdata(L, src_func); 1304 | 1305 | lua_getfield(L, LUA_REGISTRYINDEX, LUAA_REGISTRYPREFIX "functions"); 1306 | lua_getfield(L, -1, name); 1307 | lua_remove(L, -2); 1308 | 1309 | lua_settable(L, -3); 1310 | lua_pop(L, 1); 1311 | 1312 | } 1313 | -------------------------------------------------------------------------------- /lautoc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** LuaAutoC - Automagically use C Functions and Structs with the Lua API 3 | ** https://github.com/orangeduck/LuaAutoC 4 | ** Daniel Holden - contact@theorangeduck.com 5 | ** Licensed under BSD 6 | */ 7 | 8 | #ifndef lautoc_h 9 | #define lautoc_h 10 | 11 | #ifndef LUAA_LUAIMPLEMENTATION 12 | #define LUAA_LUAIMPLEMENTATION 13 | #include "lua.h" 14 | #include "lualib.h" 15 | #include "lauxlib.h" 16 | #endif 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | /* 26 | ** Open / Close 27 | */ 28 | 29 | #define LUAA_REGISTRYPREFIX "lautoc_" 30 | 31 | void luaA_open(lua_State* L); 32 | void luaA_close(lua_State* L); 33 | 34 | /* 35 | ** Types 36 | */ 37 | 38 | #define luaA_type(L, type) luaA_type_add(L, #type, sizeof(type)) 39 | 40 | enum { 41 | LUAA_INVALID_TYPE = -1 42 | }; 43 | 44 | typedef lua_Integer luaA_Type; 45 | typedef int (*luaA_Pushfunc)(lua_State*, luaA_Type, const void*); 46 | typedef void (*luaA_Tofunc)(lua_State*, luaA_Type, void*, int); 47 | 48 | luaA_Type luaA_type_add(lua_State* L, const char* type, size_t size); 49 | luaA_Type luaA_type_find(lua_State* L, const char* type); 50 | 51 | const char* luaA_typename(lua_State* L, luaA_Type id); 52 | size_t luaA_typesize(lua_State* L, luaA_Type id); 53 | 54 | /* 55 | ** Stack 56 | */ 57 | 58 | #define luaA_push(L, type, c_in) luaA_push_type(L, luaA_type(L, type), c_in) 59 | #define luaA_to(L, type, c_out, index) luaA_to_type(L, luaA_type(L, type), c_out, index) 60 | 61 | #define luaA_conversion(L, type, push_func, to_func) luaA_conversion_type(L, luaA_type(L, type), push_func, to_func); 62 | #define luaA_conversion_push(L, type, func) luaA_conversion_push_type(L, luaA_type(L, type), func) 63 | #define luaA_conversion_to(L, type, func) luaA_conversion_to_type(L, luaA_type(L, type), func) 64 | 65 | #define luaA_conversion_registered(L, type) luaA_conversion_registered_type(L, luaA_type(L, type)); 66 | #define luaA_conversion_push_registered(L, type) luaA_conversion_push_registered_typ(L, luaA_type(L, type)); 67 | #define luaA_conversion_to_registered(L, type) luaA_conversion_to_registered_type(L, luaA_type(L, type)); 68 | 69 | int luaA_push_type(lua_State* L, luaA_Type type, const void* c_in); 70 | void luaA_to_type(lua_State* L, luaA_Type type, void* c_out, int index); 71 | 72 | void luaA_conversion_type(lua_State* L, luaA_Type type_id, luaA_Pushfunc push_func, luaA_Tofunc to_func); 73 | void luaA_conversion_push_type(lua_State* L, luaA_Type type_id, luaA_Pushfunc func); 74 | void luaA_conversion_to_type(lua_State* L, luaA_Type type_id, luaA_Tofunc func); 75 | 76 | bool luaA_conversion_registered_type(lua_State* L, luaA_Type type); 77 | bool luaA_conversion_push_registered_type(lua_State* L, luaA_Type type); 78 | bool luaA_conversion_to_registered_type(lua_State* L, luaA_Type type); 79 | 80 | int luaA_push_bool(lua_State* L, luaA_Type, const void* c_in); 81 | int luaA_push_char(lua_State* L, luaA_Type, const void* c_in); 82 | int luaA_push_signed_char(lua_State* L,luaA_Type, const void* c_in); 83 | int luaA_push_unsigned_char(lua_State* L, luaA_Type, const void* c_in); 84 | int luaA_push_short(lua_State* L, luaA_Type, const void* c_in); 85 | int luaA_push_unsigned_short(lua_State* L, luaA_Type, const void* c_in); 86 | int luaA_push_int(lua_State* L, luaA_Type, const void* c_in); 87 | int luaA_push_unsigned_int(lua_State* L, luaA_Type, const void* c_in); 88 | int luaA_push_long(lua_State* L, luaA_Type, const void* c_in); 89 | int luaA_push_unsigned_long(lua_State* L, luaA_Type, const void* c_in); 90 | int luaA_push_long_long(lua_State* L, luaA_Type, const void* c_in); 91 | int luaA_push_unsigned_long_long(lua_State* L, luaA_Type, const void* c_in); 92 | int luaA_push_float(lua_State* L, luaA_Type, const void* c_in); 93 | int luaA_push_double(lua_State* L, luaA_Type, const void* c_in); 94 | int luaA_push_long_double(lua_State* L, luaA_Type, const void* c_in); 95 | int luaA_push_char_ptr(lua_State* L, luaA_Type, const void* c_in); 96 | int luaA_push_const_char_ptr(lua_State* L, luaA_Type, const void* c_in); 97 | int luaA_push_void_ptr(lua_State* L, luaA_Type, const void* c_in); 98 | int luaA_push_void(lua_State* L, luaA_Type, const void* c_in); 99 | 100 | void luaA_to_bool(lua_State* L, luaA_Type, void* c_out, int index); 101 | void luaA_to_char(lua_State* L, luaA_Type, void* c_out, int index); 102 | void luaA_to_signed_char(lua_State* L, luaA_Type, void* c_out, int index); 103 | void luaA_to_unsigned_char(lua_State* L, luaA_Type, void* c_out, int index); 104 | void luaA_to_short(lua_State* L, luaA_Type, void* c_out, int index); 105 | void luaA_to_unsigned_short(lua_State* L, luaA_Type, void* c_out, int index); 106 | void luaA_to_int(lua_State* L, luaA_Type, void* c_out, int index); 107 | void luaA_to_unsigned_int(lua_State* L, luaA_Type, void* c_out, int index); 108 | void luaA_to_long(lua_State* L, luaA_Type, void* c_out, int index); 109 | void luaA_to_unsigned_long(lua_State* L, luaA_Type, void* c_out, int index); 110 | void luaA_to_long_long(lua_State* L, luaA_Type, void* c_out, int index); 111 | void luaA_to_unsigned_long_long(lua_State* L, luaA_Type, void* c_out, int index); 112 | void luaA_to_float(lua_State* L, luaA_Type, void* c_out, int index); 113 | void luaA_to_double(lua_State* L, luaA_Type, void* c_out, int index); 114 | void luaA_to_long_double(lua_State* L, luaA_Type, void* c_out, int index); 115 | void luaA_to_char_ptr(lua_State* L, luaA_Type, void* c_out, int index); 116 | void luaA_to_const_char_ptr(lua_State* L, luaA_Type, void* c_out, int index); 117 | void luaA_to_void_ptr(lua_State* L, luaA_Type, void* c_out, int index); 118 | 119 | /* 120 | ** Structs 121 | */ 122 | #define LUAA_INVALID_MEMBER_NAME NULL 123 | 124 | #define luaA_struct(L, type) luaA_struct_type(L, luaA_type(L, type)) 125 | #define luaA_struct_member(L, type, member, member_type) luaA_struct_member_type(L, luaA_type(L, type), #member, luaA_type(L, member_type), offsetof(type, member)) 126 | 127 | #define luaA_struct_push(L, type, c_in) luaA_struct_push_type(L, luaA_type(L, type), c_in) 128 | #define luaA_struct_push_member(L, type, member, c_in) luaA_struct_push_member_offset_type(L, luaA_type(L, type), offsetof(type, member), c_in) 129 | #define luaA_struct_push_member_name(L, type, member, c_in) luaA_struct_push_member_name_type(L, luaA_type(L, type), member, c_in) 130 | 131 | #define luaA_struct_to(L, type, c_out, index) luaA_struct_to_type(L, luaA_type(L, type), c_out, index) 132 | #define luaA_struct_to_member(L, type, member, c_out, index) luaA_struct_to_member_offset_type(L, luaA_type(L, type), offsetof(type, member), c_out, index) 133 | #define luaA_struct_to_member_name(L, type, member, c_out, index) luaA_struct_to_member_name_type(L, luaA_type(L, type), member, c_out, index) 134 | 135 | #define luaA_struct_has_member(L, type, member) luaA_struct_has_member_offset_type(L, luaA_type(L, type), offsetof(type, member)) 136 | #define luaA_struct_has_member_name(L, type, member) luaA_struct_has_member_name_type(L, luaA_type(L, type), member) 137 | 138 | #define luaA_struct_typeof_member(L, type, member) luaA_struct_typeof_member_offset_type(L, luaA_type(L, type), offsetof(type, member)) 139 | #define luaA_struct_typeof_member_name(L, type, member) luaA_struct_typeof_member_name_type(L, luaA_type(L, type), member) 140 | 141 | #define luaA_struct_registered(L, type) luaA_struct_registered_type(L, luaA_type(L, type)) 142 | #define luaA_struct_next_member_name(L, type, member) luaA_struct_next_member_name_type(L, luaA_type(L,type), member) 143 | 144 | void luaA_struct_type(lua_State* L, luaA_Type type); 145 | void luaA_struct_member_type(lua_State* L, luaA_Type type, const char* member, luaA_Type member_type, size_t offset); 146 | 147 | int luaA_struct_push_type(lua_State* L, luaA_Type type, const void* c_in); 148 | int luaA_struct_push_member_offset_type(lua_State* L, luaA_Type type, size_t offset, const void* c_in); 149 | int luaA_struct_push_member_name_type(lua_State* L, luaA_Type type, const char* member, const void* c_in); 150 | 151 | void luaA_struct_to_type(lua_State* L, luaA_Type type, void* c_out, int index); 152 | void luaA_struct_to_member_offset_type(lua_State* L, luaA_Type type, size_t offset, void* c_out, int index); 153 | void luaA_struct_to_member_name_type(lua_State* L, luaA_Type type, const char* member, void* c_out, int index); 154 | 155 | bool luaA_struct_has_member_offset_type(lua_State* L, luaA_Type type, size_t offset); 156 | bool luaA_struct_has_member_name_type(lua_State* L, luaA_Type type, const char* member); 157 | 158 | luaA_Type luaA_struct_typeof_member_offset_type(lua_State* L, luaA_Type type, size_t offset); 159 | luaA_Type luaA_struct_typeof_member_name_type(lua_State* L, luaA_Type type, const char* member); 160 | 161 | bool luaA_struct_registered_type(lua_State* L, luaA_Type type); 162 | 163 | const char* luaA_struct_next_member_name_type(lua_State* L, luaA_Type type, const char* member); 164 | 165 | /* 166 | ** Enums 167 | */ 168 | 169 | #define luaA_enum(L, type) luaA_enum_type(L, luaA_type(L, type), sizeof(type)) 170 | #define luaA_enum_value(L, type, value) luaA_enum_value_type(L, luaA_type(L, type), (const type[]){value}, #value); 171 | #define luaA_enum_value_name(L, type, value, name) luaA_enum_value_type(L, luaA_type(L, type), (const type[]){value}, name); 172 | 173 | #define luaA_enum_push(L, type, c_in) luaA_enum_push_type(L, luaA_type(L, type), c_in) 174 | #define luaA_enum_to(L, type, c_out, index) luaA_enum_to_type(L, luaA_type(L, type), c_out, index) 175 | 176 | #define luaA_enum_has_value(L, type, value) luaA_enum_has_value_type(L, luaA_type(L, type), (const type[]){value}) 177 | #define luaA_enum_has_name(L, type, name) luaA_enum_has_name_type(L, luaA_type(L, type), name) 178 | 179 | #define luaA_enum_registered(L, type) luaA_enum_registered_type(L, luaA_type(L, type)) 180 | #define luaA_enum_next_value_name(L, type, member) luaA_enum_next_value_name_type(L, luaA_type(L,type), member) 181 | 182 | void luaA_enum_type(lua_State* L, luaA_Type type, size_t size); 183 | void luaA_enum_value_type(lua_State *L, luaA_Type type, const void* value, const char* name); 184 | 185 | int luaA_enum_push_type(lua_State *L, luaA_Type type, const void* c_in); 186 | void luaA_enum_to_type(lua_State* L, luaA_Type type, void *c_out, int index); 187 | 188 | bool luaA_enum_has_value_type(lua_State* L, luaA_Type type, const void* value); 189 | bool luaA_enum_has_name_type(lua_State* L, luaA_Type type, const char* name); 190 | 191 | bool luaA_enum_registered_type(lua_State *L, luaA_Type type); 192 | const char* luaA_enum_next_value_name_type(lua_State* L, luaA_Type type, const char* member); 193 | 194 | /* 195 | ** Functions 196 | */ 197 | 198 | #include "lautocall.h" 199 | 200 | #define luaA_function(L, func, ret_t, ...) luaA_function_declare(func, ret_t, ##__VA_ARGS__); luaA_function_register(L, func, ret_t, ##__VA_ARGS__) 201 | #define luaA_function_declare(func, ret_t, ...) LUAA_DECLARE(func, ret_t, LUAA_COUNT(__VA_ARGS__), LUAA_SUFFIX(ret_t), ##__VA_ARGS__) 202 | #define luaA_function_register(L, func, ret_t, ...) LUAA_REGISTER(L, func, ret_t, LUAA_COUNT(__VA_ARGS__), ##__VA_ARGS__) 203 | 204 | enum { 205 | LUAA_RETURN_STACK_SIZE = 256, 206 | LUAA_ARGUMENT_STACK_SIZE = 2048 207 | }; 208 | 209 | typedef void (*luaA_Func)(void*, void*); 210 | 211 | int luaA_call(lua_State* L, void* func_ptr); 212 | int luaA_call_name(lua_State* L, const char* func_name); 213 | 214 | void luaA_function_register_type(lua_State* L, void* src_func, luaA_Func auto_func, const char* name, luaA_Type ret_tid, int num_args, ...); 215 | 216 | #endif 217 | -------------------------------------------------------------------------------- /lautoc.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | -- LuaAutoC - Automagically use C Functions and Structs with the Lua API 3 | -- https://github.com/orangeduck/LuaAutoC 4 | -- Daniel Holden - contact@theorangeduck.com 5 | -- Licensed under BSD 6 | 7 | -- Findall Function 8 | 9 | function findall(text, pattern) 10 | local matches = {} 11 | for word in string.gmatch(text, pattern) do 12 | table.insert(matches, word) 13 | end 14 | return matches 15 | end 16 | 17 | -- String Split Function 18 | 19 | function string:split(sep) 20 | local sep, fields = sep or ":", {} 21 | local pattern = string.format("([^%s]+)", sep) 22 | self:gsub(pattern, function(c) fields[#fields+1] = c end) 23 | return fields 24 | end 25 | 26 | -- Check Arguments 27 | 28 | if #arg ~= 1 then 29 | print('Usage: lua lautoc.lua ') 30 | return 31 | end 32 | 33 | -- Open Header 34 | 35 | local file = io.open(arg[1], 'r') 36 | 37 | if file == nil then 38 | print(string.format('Error: Cannot load file "%s"', arg[1])) 39 | return 40 | end 41 | 42 | local text = file:read('*all') 43 | 44 | io.close(file) 45 | 46 | -- Remove all newlines 47 | 48 | local text = string.gsub(text, "\r", "") 49 | local text = string.gsub(text, "\n", "") 50 | 51 | -- Find all typedefs, structs, and functions 52 | 53 | typestrts = findall(text, "typedef struct {.-} %w-;") 54 | typeenums = findall(text, "typedef enum {.-} %w-;") 55 | funcs = findall(text, "[%w%*]- [%w_]-%(.-%);") 56 | 57 | -- Output Typedef Enum Code 58 | 59 | for k,v in pairs(typeenums) do 60 | local _, _, members, typename = string.find(v, "typedef enum {(.-)} (%w-);") 61 | 62 | print(string.format("luaA_enum(%s);", typename)) 63 | 64 | for _, mem in pairs(members:split(",")) do 65 | local _, _, name = string.find(mem, "(%w+)") 66 | print(string.format("luaA_enum_value(%s, %s);", typename, name)) 67 | end 68 | 69 | print("") 70 | end 71 | 72 | -- Output Typedef Struct Code 73 | 74 | for k,v in pairs(typestrts) do 75 | local _, _, members, typename = string.find(v, "typedef struct {(.-)} (%w-);") 76 | 77 | print(string.format("luaA_struct(%s);", typename)) 78 | 79 | for _, mem in pairs(members:split(";")) do 80 | local meminfo = mem:split(" ") 81 | print(string.format("luaA_struct_member(%s, %s, %s);", typename, meminfo[2], meminfo[1])) 82 | end 83 | 84 | print("") 85 | end 86 | 87 | -- Output Function Code 88 | 89 | for k,v in pairs(funcs) do 90 | local _, _, typename, name, args = string.find(v, "([%w%*]-) ([%w_]-)%((.-)%);") 91 | 92 | local argtypes = {} 93 | for _, arg in pairs(args:split(",")) do 94 | table.insert(argtypes, arg:split(" ")[1]) 95 | end 96 | 97 | local fstring = string.format("luaA_function(%s, %s", name, typename) 98 | for _, v in pairs(argtypes) do 99 | fstring = fstring .. string.format(", %s", v) 100 | end 101 | local fstring = fstring .. ");" 102 | 103 | print(fstring) 104 | end 105 | 106 | -------------------------------------------------------------------------------- /lautocall.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** macros to wrap function registration 3 | ** 4 | ** creates an inline function definition 5 | ** using a set calling convention 6 | ** which allows for automatic calling 7 | */ 8 | 9 | #ifndef lautocall_h 10 | #define lautocall_h 11 | 12 | #define LUAA_EVAL(...) __VA_ARGS__ 13 | 14 | /* Join Three Strings */ 15 | #define LUAA_JOIN2(X, Y) X ## Y 16 | #define LUAA_JOIN3(X, Y, Z) X ## Y ## Z 17 | 18 | /* workaround for MSVC VA_ARGS expansion */ 19 | #define LUAA_APPLY(FUNC, ARGS) LUAA_EVAL(FUNC ARGS) 20 | 21 | /* Argument Counter */ 22 | #define LUAA_COUNT(...) LUAA_COUNT_COLLECT(_, ##__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 23 | #define LUAA_COUNT_COLLECT(...) LUAA_COUNT_SHIFT(__VA_ARGS__) 24 | #define LUAA_COUNT_SHIFT(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _N, ...) _N 25 | 26 | /* Detect Void */ 27 | #define LUAA_VOID(X) LUAA_JOIN2(LUAA_VOID_, X) 28 | #define LUAA_VOID_void 29 | #define LUAA_CHECK_N(X, N, ...) N 30 | #define LUAA_CHECK(...) LUAA_CHECK_N(__VA_ARGS__, ,) 31 | #define LUAA_SUFFIX(X) LUAA_SUFFIX_CHECK(LUAA_VOID(X)) 32 | #define LUAA_SUFFIX_CHECK(X) LUAA_CHECK(LUAA_JOIN2(LUAA_SUFFIX_, X)) 33 | #define LUAA_SUFFIX_ ~, _void, 34 | 35 | /* Declaration and Register Macros */ 36 | #define LUAA_DECLARE(func, ret_t, count, suffix, ...) LUAA_APPLY(LUAA_JOIN3(luaA_function_declare, count, suffix), (func, ret_t, ##__VA_ARGS__)) 37 | //#define LUAA_DECLARE(func, ret_t, count, suffix, ...) LUAA_APPLY(LUAA_JOIN3(luaA_function_declare, count, suffix), (func, ret_t, ##__VA_ARGS__)) 38 | #define LUAA_REGISTER(L, func, ret_t, count, ...) LUAA_APPLY(LUAA_JOIN2(luaA_function_register, count), (L, func, ret_t, ##__VA_ARGS__)) 39 | 40 | /* 41 | ** MSVC does not allow nested functions 42 | ** so function is wrapped in nested struct 43 | */ 44 | #ifdef _MSC_VER 45 | 46 | #define luaA_function_declare0(func, ret_t) \ 47 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 48 | *(ret_t*)out = func(); }; } 49 | 50 | #define luaA_function_declare0_void(func, ret_t) \ 51 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 52 | func(); }; } 53 | 54 | #define luaA_function_declare1(func, ret_t, arg0_t) \ 55 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 56 | arg0_t a0 = *(arg0_t*)args; \ 57 | *(ret_t*)out = func(a0); }; } 58 | 59 | #define luaA_function_declare1_void(func, ret_t, arg0_t) \ 60 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 61 | arg0_t a0 = *(arg0_t*)args; \ 62 | func(a0); }; } 63 | 64 | #define luaA_function_declare2(func, ret_t, arg0_t, arg1_t) \ 65 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 66 | arg0_t a0 = *(arg0_t*)args; \ 67 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 68 | *(ret_t*)out = func(a0, a1); }; } 69 | 70 | #define luaA_function_declare2_void(func, ret_t, arg0_t, arg1_t) \ 71 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 72 | arg0_t a0 = *(arg0_t*)args; \ 73 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 74 | func(a0, a1); }; } 75 | 76 | #define luaA_function_declare3(func, ret_t, arg0_t, arg1_t, arg2_t) \ 77 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 78 | arg0_t a0 = *(arg0_t*)args; \ 79 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 80 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 81 | *(ret_t*)out = func(a0, a1, a2); }; } 82 | 83 | #define luaA_function_declare3_void(func, ret_t, arg0_t, arg1_t, arg2_t) \ 84 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 85 | arg0_t a0 = *(arg0_t*)args; \ 86 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 87 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 88 | func(a0, a1, a2); }; } 89 | 90 | #define luaA_function_declare4(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t) \ 91 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 92 | arg0_t a0 = *(arg0_t*)args; \ 93 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 94 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 95 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 96 | *(ret_t*)out = func(a0, a1, a2, a3); }; } 97 | 98 | #define luaA_function_declare4_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t) \ 99 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 100 | arg0_t a0 = *(arg0_t*)args; \ 101 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 102 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 103 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 104 | func(a0, a1, a2, a3); }; } 105 | 106 | #define luaA_function_declare5(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t) \ 107 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 108 | arg0_t a0 = *(arg0_t*)args; \ 109 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 110 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 111 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 112 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 113 | *(ret_t*)out = func(a0, a1, a2, a3, a4); }; } 114 | 115 | #define luaA_function_declare5_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t) \ 116 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 117 | arg0_t a0 = *(arg0_t*)args; \ 118 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 119 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 120 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 121 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 122 | func(a0, a1, a2, a3, a4); }; } 123 | 124 | #define luaA_function_declare6(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t) \ 125 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 126 | arg0_t a0 = *(arg0_t*)args; \ 127 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 128 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 129 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 130 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 131 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 132 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5); }; } 133 | 134 | #define luaA_function_declare6_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t) \ 135 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 136 | arg0_t a0 = *(arg0_t*)args; \ 137 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 138 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 139 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 140 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 141 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 142 | func(a0, a1, a2, a3, a4, a5); }; } 143 | 144 | #define luaA_function_declare7(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t) \ 145 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 146 | arg0_t a0 = *(arg0_t*)args; \ 147 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 148 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 149 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 150 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 151 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 152 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 153 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5, a6); }; } 154 | 155 | #define luaA_function_declare7_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t) \ 156 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 157 | arg0_t a0 = *(arg0_t*)args; \ 158 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 159 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 160 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 161 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 162 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 163 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 164 | func(a0, a1, a2, a3, a4, a5, a6); }; } 165 | 166 | #define luaA_function_declare8(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t) \ 167 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 168 | arg0_t a0 = *(arg0_t*)args; \ 169 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 170 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 171 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 172 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 173 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 174 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 175 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 176 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5, a6, a7); }; } 177 | 178 | #define luaA_function_declare8_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t) \ 179 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 180 | arg0_t a0 = *(arg0_t*)args; \ 181 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 182 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 183 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 184 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 185 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 186 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 187 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 188 | func(a0, a1, a2, a3, a4, a5, a6, a7); }; } 189 | 190 | #define luaA_function_declare9(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t) \ 191 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 192 | arg0_t a0 = *(arg0_t*)args; \ 193 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 194 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 195 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 196 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 197 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 198 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 199 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 200 | arg8_t a8 = *(arg8_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)); \ 201 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5, a6, a7, a8); }; } 202 | 203 | #define luaA_function_declare9_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t) \ 204 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 205 | arg0_t a0 = *(arg0_t*)args; \ 206 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 207 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 208 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 209 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 210 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 211 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 212 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 213 | arg8_t a8 = *(arg8_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)); \ 214 | func(a0, a1, a2, a3, a4, a5, a6, a7, a8); }; } 215 | 216 | #define luaA_function_declare10(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t, arg9_t) \ 217 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 218 | arg0_t a0 = *(arg0_t*)args; \ 219 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 220 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 221 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 222 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 223 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 224 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 225 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 226 | arg8_t a8 = *(arg8_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)); \ 227 | arg9_t a9 = *(arg9_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)+sizeof(arg8_t)); \ 228 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }; } 229 | 230 | #define luaA_function_declare10_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t, arg9_t) \ 231 | struct __luaA_wrap_##func { static void __luaA_##func(char* out, char* args) { \ 232 | arg0_t a0 = *(arg0_t*)args; \ 233 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 234 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 235 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 236 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 237 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 238 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 239 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 240 | arg8_t a8 = *(arg8_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)); \ 241 | arg9_t a9 = *(arg9_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)+sizeof(arg8_t)); \ 242 | func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }; } 243 | 244 | 245 | #define luaA_function_register0(L, func, ret_t) \ 246 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 0) 247 | 248 | #define luaA_function_register1(L, func, ret_t, arg0_t) \ 249 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 1, luaA_type(L, arg0_t)) 250 | 251 | #define luaA_function_register2(L, func, ret_t, arg0_t, arg1_t) \ 252 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 2, luaA_type(L, arg0_t), luaA_type(L, arg1_t)) 253 | 254 | #define luaA_function_register3(L, func, ret_t, arg0_t, arg1_t, arg2_t) \ 255 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 3, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t)) 256 | 257 | #define luaA_function_register4(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t) \ 258 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 4, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t)) 259 | 260 | #define luaA_function_register5(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t) \ 261 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 5, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t)) 262 | 263 | #define luaA_function_register6(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t) \ 264 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 6, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t)) 265 | 266 | #define luaA_function_register7(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t) \ 267 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 7, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t), luaA_type(L, arg6_t)) 268 | 269 | #define luaA_function_register8(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t) \ 270 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 8, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t), luaA_type(L, arg6_t), luaA_type(L, arg7_t)) 271 | 272 | #define luaA_function_register9(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t) \ 273 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 9, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t), luaA_type(L, arg6_t), luaA_type(L, arg7_t), luaA_type(L, arg8_t)) 274 | 275 | #define luaA_function_register10(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t, arg9_t) \ 276 | luaA_function_register_type(L, func, (luaA_Func)__luaA_wrap_##func::__luaA_##func, #func, luaA_type(L, ret_t), 10, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t), luaA_type(L, arg6_t), luaA_type(L, arg7_t), luaA_type(L, arg8_t), luaA_type(L, arg9_t)) 277 | 278 | 279 | #else 280 | 281 | 282 | #define luaA_function_declare0(func, ret_t) \ 283 | void __luaA_##func(void* out, void* args) { \ 284 | *(ret_t*)out = func(); } 285 | 286 | #define luaA_function_declare0_void(func, ret_t) \ 287 | void __luaA_##func(void* out, void* args) { \ 288 | func(); } 289 | 290 | #define luaA_function_declare1(func, ret_t, arg0_t) \ 291 | void __luaA_##func(void* out, void* args) { \ 292 | arg0_t a0 = *(arg0_t*)args; \ 293 | *(ret_t*)out = func(a0); } 294 | 295 | #define luaA_function_declare1_void(func, ret_t, arg0_t) \ 296 | void __luaA_##func(void* out, void* args) { \ 297 | arg0_t a0 = *(arg0_t*)args; \ 298 | func(a0); } 299 | 300 | #define luaA_function_declare2(func, ret_t, arg0_t, arg1_t) \ 301 | void __luaA_##func(void* out, void* args) { \ 302 | arg0_t a0 = *(arg0_t*)args; \ 303 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 304 | *(ret_t*)out = func(a0, a1); } 305 | 306 | #define luaA_function_declare2_void(func, ret_t, arg0_t, arg1_t) \ 307 | void __luaA_##func(void* out, void* args) { \ 308 | arg0_t a0 = *(arg0_t*)args; \ 309 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 310 | func(a0, a1); } 311 | 312 | #define luaA_function_declare3(func, ret_t, arg0_t, arg1_t, arg2_t) \ 313 | void __luaA_##func(void* out, void* args) { \ 314 | arg0_t a0 = *(arg0_t*)args; \ 315 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 316 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 317 | *(ret_t*)out = func(a0, a1, a2); } 318 | 319 | #define luaA_function_declare3_void(func, ret_t, arg0_t, arg1_t, arg2_t) \ 320 | void __luaA_##func(void* out, void* args) { \ 321 | arg0_t a0 = *(arg0_t*)args; \ 322 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 323 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 324 | func(a0, a1, a2); } 325 | 326 | #define luaA_function_declare4(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t) \ 327 | void __luaA_##func(void* out, void* args) { \ 328 | arg0_t a0 = *(arg0_t*)args; \ 329 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 330 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 331 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 332 | *(ret_t*)out = func(a0, a1, a2, a3); } 333 | 334 | #define luaA_function_declare4_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t) \ 335 | void __luaA_##func(void* out, void* args) { \ 336 | arg0_t a0 = *(arg0_t*)args; \ 337 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 338 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 339 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 340 | func(a0, a1, a2, a3); } 341 | 342 | #define luaA_function_declare5(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t) \ 343 | void __luaA_##func(void* out, void* args) { \ 344 | arg0_t a0 = *(arg0_t*)args; \ 345 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 346 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 347 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 348 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 349 | *(ret_t*)out = func(a0, a1, a2, a3, a4); } 350 | 351 | #define luaA_function_declare5_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t) \ 352 | void __luaA_##func(void* out, void* args) { \ 353 | arg0_t a0 = *(arg0_t*)args; \ 354 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 355 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 356 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 357 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 358 | func(a0, a1, a2, a3, a4); } 359 | 360 | #define luaA_function_declare6(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t) \ 361 | void __luaA_##func(void* out, void* args) { \ 362 | arg0_t a0 = *(arg0_t*)args; \ 363 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 364 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 365 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 366 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 367 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 368 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5); } 369 | 370 | #define luaA_function_declare6_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t) \ 371 | void __luaA_##func(void* out, void* args) { \ 372 | arg0_t a0 = *(arg0_t*)args; \ 373 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 374 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 375 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 376 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 377 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 378 | func(a0, a1, a2, a3, a4, a5); } 379 | 380 | #define luaA_function_declare7(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t) \ 381 | void __luaA_##func(void* out, void* args) { \ 382 | arg0_t a0 = *(arg0_t*)args; \ 383 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 384 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 385 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 386 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 387 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 388 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 389 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5, a6); } 390 | 391 | #define luaA_function_declare7_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t) \ 392 | void __luaA_##func(void* out, void* args) { \ 393 | arg0_t a0 = *(arg0_t*)args; \ 394 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 395 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 396 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 397 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 398 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 399 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 400 | func(a0, a1, a2, a3, a4, a5, a6); } 401 | 402 | #define luaA_function_declare8(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t) \ 403 | void __luaA_##func(void* out, void* args) { \ 404 | arg0_t a0 = *(arg0_t*)args; \ 405 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 406 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 407 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 408 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 409 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 410 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 411 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 412 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5, a6, a7); } 413 | 414 | #define luaA_function_declare8_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t) \ 415 | void __luaA_##func(void* out, void* args) { \ 416 | arg0_t a0 = *(arg0_t*)args; \ 417 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 418 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 419 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 420 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 421 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 422 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 423 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 424 | func(a0, a1, a2, a3, a4, a5, a6, a7); } 425 | 426 | #define luaA_function_declare9(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t) \ 427 | void __luaA_##func(void* out, void* args) { \ 428 | arg0_t a0 = *(arg0_t*)args; \ 429 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 430 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 431 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 432 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 433 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 434 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 435 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 436 | arg8_t a8 = *(arg8_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)); \ 437 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5, a6, a7, a8); } 438 | 439 | #define luaA_function_declare9_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t) \ 440 | void __luaA_##func(void* out, void* args) { \ 441 | arg0_t a0 = *(arg0_t*)args; \ 442 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 443 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 444 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 445 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 446 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 447 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 448 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 449 | arg8_t a8 = *(arg8_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)); \ 450 | func(a0, a1, a2, a3, a4, a5, a6, a7, a8); } 451 | 452 | #define luaA_function_declare10(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t, arg9_t) \ 453 | void __luaA_##func(void* out, void* args) { \ 454 | arg0_t a0 = *(arg0_t*)args; \ 455 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 456 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 457 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 458 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 459 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 460 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 461 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 462 | arg8_t a8 = *(arg8_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)); \ 463 | arg9_t a9 = *(arg9_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)+sizeof(arg8_t)); \ 464 | *(ret_t*)out = func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); } 465 | 466 | #define luaA_function_declare10_void(func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t, arg9_t) \ 467 | void __luaA_##func(void* out, void* args) { \ 468 | arg0_t a0 = *(arg0_t*)args; \ 469 | arg1_t a1 = *(arg1_t*)(args+sizeof(arg0_t)); \ 470 | arg2_t a2 = *(arg2_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)); \ 471 | arg3_t a3 = *(arg3_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)); \ 472 | arg4_t a4 = *(arg4_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)); \ 473 | arg5_t a5 = *(arg5_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)); \ 474 | arg6_t a6 = *(arg6_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)); \ 475 | arg7_t a7 = *(arg7_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)); \ 476 | arg8_t a8 = *(arg8_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)); \ 477 | arg9_t a9 = *(arg9_t*)(args+sizeof(arg0_t)+sizeof(arg1_t)+sizeof(arg2_t)+sizeof(arg3_t)+sizeof(arg4_t)+sizeof(arg5_t)+sizeof(arg6_t)+sizeof(arg7_t)+sizeof(arg8_t)); \ 478 | func(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); } 479 | 480 | 481 | #define luaA_function_register0(L, func, ret_t) \ 482 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 0) 483 | 484 | #define luaA_function_register1(L, func, ret_t, arg0_t) \ 485 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 1, luaA_type(L, arg0_t)) 486 | 487 | #define luaA_function_register2(L, func, ret_t, arg0_t, arg1_t) \ 488 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 2, luaA_type(L, arg0_t), luaA_type(L, arg1_t)) 489 | 490 | #define luaA_function_register3(L, func, ret_t, arg0_t, arg1_t, arg2_t) \ 491 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 3, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t)) 492 | 493 | #define luaA_function_register4(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t) \ 494 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 4, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t)) 495 | 496 | #define luaA_function_register5(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t) \ 497 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 5, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t)) 498 | 499 | #define luaA_function_register6(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t) \ 500 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 6, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t)) 501 | 502 | #define luaA_function_register7(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t) \ 503 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 7, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t), luaA_type(L, arg6_t)) 504 | 505 | #define luaA_function_register8(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t) \ 506 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 8, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t), luaA_type(L, arg6_t), luaA_type(L, arg7_t)) 507 | 508 | #define luaA_function_register9(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t) \ 509 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 9, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t), luaA_type(L, arg6_t), luaA_type(L, arg7_t), luaA_type(L, arg8_t)) 510 | 511 | #define luaA_function_register10(L, func, ret_t, arg0_t, arg1_t, arg2_t, arg3_t, arg4_t, arg5_t, arg6_t, arg7_t, arg8_t, arg9_t) \ 512 | luaA_function_register_type(L, func, __luaA_##func, #func, luaA_type(L, ret_t), 10, luaA_type(L, arg0_t), luaA_type(L, arg1_t), luaA_type(L, arg2_t), luaA_type(L, arg3_t), luaA_type(L, arg4_t), luaA_type(L, arg5_t), luaA_type(L, arg6_t), luaA_type(L, arg7_t), luaA_type(L, arg8_t), luaA_type(L, arg9_t)) 513 | 514 | 515 | #endif 516 | 517 | #endif 518 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LuaAutoC", 3 | "version": "2.0.1", 4 | "repo": "orangeduck/LuaAutoC", 5 | "description": "Automagically use C Functions and Structs with the Lua API", 6 | "keywords": ["c", "lua", "api", "automatic", "functions", "structs"], 7 | "license": "BSD", 8 | "src": ["lautoc.c", "lautoc.h", "lautocall.h"] 9 | } 10 | --------------------------------------------------------------------------------