Reputation: 477
I'm using Lua to call a dll file. my c/c++ code is like this:
#include <iostream>
extern "C"{
#include "lua.hpp"
#include "lualib.h"
#include "lauxlib.h"
}
using namespace std;
typedef struct StructA{
int a;
} structA;
typedef struct StructB{
char *b;
} structB;
static int createA(lua_State *L)
{
int n = lua_gettop(L);
size_t iBytes = sizeof(struct StructA);
struct StructA *sa;
sa = (StructA *)lua_newuserdata(L, iBytes);
sa->a = 1;
return 1;
}
static int createB(lua_State *L)
{
int n = lua_gettop(L);
size_t iBytes = sizeof(struct StructB);
struct StructB *sb;
sb = (StructB *)lua_newuserdata(L, iBytes);
sb->b = "2";
return 1;
}
static int print(lua_State *L)
{
if("some condition")//struct type is StructA
{
cout<< "struct type is StructA" <<endl;
struct StructA *sa = (struct StructA *)lua_touserdata(L, 1);
cout<< "a:"<<(sa->a) <<endl;
}else if("some condition")//struct type is structB
{
cout<< "struct type is StructB" <<endl;
struct StructB *sb = (struct StructB *)lua_touserdata(L, 1);
cout<< "b:"<<(sb->b) <<endl;
}
return 0;
}
static luaL_Reg mylibs[] = {
{ "A", createA },
{ "B", createB },
{ "print", print },
{ NULL, NULL }
};
extern "C" __declspec(dllexport)
int luaopen_occi_test(lua_State* L)
{
luaL_register(L, "occi_test", mylibs);
return 1;
}
and I used VS2010 to compile this C/C++ code. My Lua code is like this:
local a = occi_test.A()
local b = occi_test.B()
occi_test.print(a)
occi_test.print(b)
as you can see,in Lua,parameter a and b are both userdata type,but in C/C++,a's type is StructA,b's type is StrcutB,so when Lua calling a C/C++ function and passing a or b,how C/C++ code find out the paramter's type?Please complete this code by replace "some condition" by something can do the job.
Upvotes: 1
Views: 781
Reputation: 48662
luaopen_occi_test
, do luaL_newmetatable(L, "StructA");
and luaL_newmetatable(L, "StructB");
. This will add metatables to the registry that you can use later.createA
and createB
, do luaL_setmetatable(L, "StructA");
and luaL_setmetatable(L, "StructB");
. This will attach the appropriate metatable you created in step 1 to the new userdata objects.print
, use luaL_testudata(L, 1, "StructA")
and luaL_testudata(L, 1, "StructB")
. These return a pointer to the userdata (which is true when converted to a Boolean) when it's a userdata with the named metatable, or a null pointer (which is false when converted to a Boolean) otherwise. Alternatively, you could slightly optimize the code by saving the results and then using just the right one, like this:static int print(lua_State *L)
{
struct StructA *sa;
struct StructB *sb;
if((sa = (struct StructA *)luaL_testudata(L, 1, "StructA")) != nullptr)
{
cout<< "struct type is StructA" <<endl;
cout<< "a:"<<(sa->a) <<endl;
}else if((sb = (struct StructB *)luaL_testudata(L, 1, "StructB")) != nullptr)
{
cout<< "struct type is StructB" <<endl;
cout<< "b:"<<(sb->b) <<endl;
}
return 0;
}
Upvotes: 0