This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The third edition targets Lua 5.2 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.


26.2 – C Libraries

A Lua library is a chunk that defines several Lua functions and stores them in appropriate places, typically as entries in a table. A C library for Lua mimics this behavior. Besides the definition of its C functions, it must also define a special function that corresponds to the main chunk of a Lua library. Once called, this function registers all C functions of the library and stores them in appropriate places. Like a Lua main chunk, it also initializes anything else that needs initialization in the library.

Lua "sees" C functions through this registration process. Once a C function is represented and stored in Lua, a Lua program calls it through direct reference to its address (which is what we give to Lua when we register a function). In other words, Lua does not depend on a function name, package location, or visibility rules to call a function, once it is registered. Typically, a C library has one single public (extern) function, which is the function that opens the library. All other functions may be private, declared as static in C.

When you extend Lua with C functions, it is a good idea to design your code as a C library, even when you want to register only one C function: Sooner or later (usually sooner) you will need other functions. As usual, the auxiliary library offers a helper function for this job. The luaL_openlib function receives a list of C functions and their respective names and registers all of them inside a table with the library name. As an example, suppose we want to create a library with the l_dir function that we defined earlier. First, we must define the library functions:

    static int l_dir (lua_State *L) {
       ...  /* as before */
    }
Next, we declare an array with all functions and their respective names. This array has elements of type luaL_reg, which is a structure with two fields: a string and a function pointer.
    static const struct luaL_reg mylib [] = {
      {"dir", l_dir},
      {NULL, NULL}  /* sentinel */
    };
In our example, there is only one function (l_dir) to declare. Notice that the last pair in the array must be {NULL, NULL}, to signal its end. Finally, we declare a main function, using luaL_openlib:
    int luaopen_mylib (lua_State *L) {
      luaL_openlib(L, "mylib", mylib, 0);
      return 1;
    }
The second argument to luaL_openlib is the library name. This function creates (or reuses) a table with the given name, and fills it with the pairs name-function specified by the array mylib. The luaL_openlib function also allows us to register common upvalues for all functions in a library. For now, we are not using upvalues, so the last argument in the call is zero. When it returns, luaL_openlib leaves on the stack the table wherein it opened the library. The luaopen_mylib function returns 1 to return this value to Lua. (As with Lua libraries, this return is optional, because the library is already assigned to a global variable. Again, like in Lua libraries, it costs nothing, and may be useful occasionally.)

After finishing the library, we must link it to the interpreter. The most convenient way to do it is with the dynamic linking facility, if your Lua interpreter supports this facility. (Remember the discussion about dynamic linking in Section 8.2.) In this case, you must create a dynamic library with your code (a .dll file in Windows, a .so file in Linux). After that, you can load your library directly from within Lua, with loadlib. The call

    mylib = loadlib("fullname-of-your-library", "luaopen_mylib")
transforms the luaopen_mylib function into a C function inside Lua and assigns this function to mylib. (That explains why luaopen_mylib must have the same prototype as any other C function.) Next, the call mylib() runs luaopen_mylib, opening the library.

If your interpreter does not support dynamic linking, then you have to recompile Lua with your new library. Besides that, you need some way to tell the stand-alone interpreter that it should open this library when it opens a new state. Some macros facilitate this task. First, you must create a header file (let us call it mylib.h) with the following content:

    int luaopen_mylib (lua_State *L);
    
    #define LUA_EXTRALIBS { "mylib", luaopen_mylib },
The first line declares the open function. The next line defines the macro LUA_EXTRALIBS as a new entry in the array of functions that the interpreter calls when it creates a new state. (This array has type struct luaL_reg[], so we need to put a name there.)

To include this header file in the interpreter, you can define the macro LUA_USERCONFIG in your compiler options. For a command-line compiler, you typically must add an option like

    -DLUA_USERCONFIG=\"mylib.h\"
(The backslashes protect the quotes from the shell; those quotes are necessary in C when we specify an include file name.) In an integrated development environment, you must add something similar in the project settings. Then, when you re-compile lua.c, it includes mylib.h, and therefore uses the new definition of LUA_EXTRALIBS in the list of libraries to open.