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

Time:04-15

I have a folder of C files that are compiled into one library and linked together, then required with Lua from a C program.

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)

Inside luargl.c, I have some problematic code:

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);
...

with output:

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

The functions are defined inside metasprite.c and included with 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 }
};

Why can I call the function but have it stay null when it's inside of the array? Further, how can I get the array to have the contents of what is described in metasprite.c?

CodePudding user response:

The array is static, i. e. unless you provide access by other means (e.g. function returning pointers into) it is only accessible from within that file:

// metasprite.c (!)

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

Thus the array is not visible from within luargl.c.

You haven't provided the header, but you must have written it in a way such that this latter file gets its own version of the array.

If you need access to such array from multiple files then you need to handle the matter differently!

// 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 might help to avoid array size collisions, but the problem remains. Though as the array is null-terminated anyway you might instead better get away with a pointer:

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

Iteration would then occur profiting from exactly that:

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