C函数在数组中为空,但直接调用时有效

C Function is null inside array, but works when called directly

我有一个 C 文件文件夹,这些文件被编译成一个库并链接在一起,然后需要 Lua 来自 C++ 程序。

CFLAGS = -std=c++17 -ggdb -O0
LDFLAGS = -llua -lrgl -lfreetype

SRC = -c src/luargl/*.c
OBJ = metasprite.o luargl.o

# luargl.o is deleted before running app
all: compile link main

compile:
    gcc -Iinclude -fPIC -Wall $(SRC) 

link:
    gcc $(OBJ) -shared -o luargl.so $(LDFLAGS)

main:
    g++ $(CFLAGS) -o app src/main.cpp $(LDFLAGS)

在 luargl.c 中,我有一些有问题的代码:

LUALIB_API int luaopen_luargl(lua_State* L) {
    state = L;

    printf("Functions: %s, %s\n", luargl_sprite_methods[0].func, luargl_sprite_methods[0].name);
    luargl_sprite_index(state);
...

输出:

// Functions: (null), (null)
// sprite index

函数在 metasprite.c 中定义并包含在 metasprite.h 中:


int luargl_sprite_index(lua_State* state) {
    printf("sprite index\n");
    return 0;
}

int luargl_sprite_newindex(lua_State* state) {
    printf("sprite newindex\n");
    return 0;
}

static const luaL_Reg luargl_sprite_methods[] = {
    { "__index", luargl_sprite_index},
    { "__newindex", luargl_sprite_newindex},

    { NULL, NULL }
};

为什么我可以调用该函数,但当它在数组内部时却保持为空?此外,如何让数组包含 metasprite.c?

中描述的内容

数组是static, i. e.除非您通过其他方式提供访问权限(例如函数返回指针),否则只能从该文件中访问它:

// metasprite.c (!)

   static const luaL_Reg luargl_sprite_methods[] = { ... };
// ^^^^^^  (!!!)

因此数组在 luargl.c.

不可见

您没有提供 header,但您必须以某种方式编写它,以便后一个文件获得它自己的数组版本。

如果您需要从多个文件访问这样的数组,那么您需要以不同的方式处理这个问题!

// metasprite.h:

extern luaL_Reg const luargl_sprite_methods[3];
//                                          ^
// unfortunately no way to get around specifying size explicitly

// metasprite.c:

luaL_Reg const luargl_sprite_methods[] { ... };
// note: NO static!

A #define 可能有助于避免数组大小冲突,但问题仍然存在。尽管数组是 null-terminated 无论如何你最好还是使用指针:

// metasprite.h:

extern luaL_Reg const* luargl_sprite_methods;
//                   ^

// metasprite.c:

static luaL_Reg const luargl_sprite_methods_[] { ... };
// NOW can be static, but needs a different name!

luaL_Reg const* luargl_sprite_methods = luargl_sprite_methods_;
// again: NO static!

然后迭代将从中获利:

for(luaL_Reg const* l = luargl_sprite_methods; l->key; ++l)
{
   // use l->func
}