1

我正在使用 Lua 调用 dll 文件。我的 c/c++ 代码是这样的:

#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;
}

我使用 VS2010 编译了这个 C/C++ 代码。我的 Lua 代码是这样的:

local a = occi_test.A()
local b = occi_test.B()
occi_test.print(a)
occi_test.print(b)

如您所见,在Lua中,参数a和b都是userdata类型,但在C/C++中,a的类型是StructA,b的类型是StrcutB,所以当Lua调用C/C++函数并传递a或b时,C如何/C++ 代码找出参数的类型?请通过将“某些条件”替换为可以完成工作的东西来完成此代码。

4

1 回答 1

0
  1. 在开头luaopen_occi_test,做luaL_newmetatable(L, "StructA");luaL_newmetatable(L, "StructB");。这会将元表添加到您以后可以使用的注册表中。
  2. 在 and 的末尾createAcreateBluaL_setmetatable(L, "StructA");and luaL_setmetatable(L, "StructB");。这会将您在步骤 1 中创建的适当元表附加到新的 userdata 对象。
  3. 对于您在 中的条件print,请使用luaL_testudata(L, 1, "StructA")luaL_testudata(L, 1, "StructB")。当它是具有命名元表的用户数据时,它们返回指向用户数据的指针(转换为布尔值时为真),否则返回空指针(转换为布尔值时为假)。或者,您可以通过保存结果然后使用正确的结果来稍微优化代码,如下所示:
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;
}
于 2020-11-21T22:45:04.650 回答