This tutorial is made mainly for Linux, but experienced users from windows will understand what to do
First things first, if you're working on a linux environment, you will want to install Lua (which you're probably using only from love), but it should not be any version, it must be the same Lua version used with Love 11.3, which is Lua 5.1, so execute the following command in your terminal
Code: Select all
sudo apt-get install lua5.1-dev
That command will install in your /usr/include/lua5.1 Lua headers for working with C.
Now, for compiling C you must install the gcc command, doing so is as simply as calling in the terminal
Code: Select all
sudo apt-get install gcc
After creating your file, you will need to import 2 main libraries in your C code, the lua lib, and the lua auxiliary lib:
Code: Select all
#include <lua.h>
#include <lauxlib.h>
After that, you will want to study some specifications on chapters: 26 to 28 from the lua.org site: https://www.lua.org/pil/contents.html
- 26=> Calling C from Lua
- 27=> Techniques for Writing C Functions
- 28=> User-Defined types in C
Every exported function must follow the following prototype:
Code: Select all
typedef int (*lua_CFunction) (lua_State *L)
Code: Select all
static int l_mult50(lua_State* L)
For getting parameters in your function you must get it's index, every parameter function starts from 1, so an example would be:
Code: Select all
double number = lua_tonumber(L, 1);
Code: Select all
double number = luaL_checknumber(L, 1)
- luaL_checkstring,
- luaL_checknumber,
- luaL_checkint,
- luaL_checkany
Code: Select all
number*= 50;
After that, we will want to return it into some variable in Lua, so how we do that?
You need to call lua_push[data](value), the most common to find using are:
- lua_pushnumber,
- lua_pushboolean,
- lua_pushstring,
- lua_pushcfunction,
- lua_pushnil,
- lua_pushvalue
Code: Select all
lua_pushnumber(L, number);
Our function must return how many values we pushed
So, in our case we must
Code: Select all
return 1
So, our finished function looks like this:
Code: Select all
static int l_mult50(lua_State* L)
{
double number = luaL_checknumber(L, 1);
lua_pushnumber(L, number*50);
return 1;
}
You will need to create another function with the prefix luaopen_
After that prefix, you need to put the filename that will be imported in your game, in our case, as it will be called libnativefunc.so (dll in Windows case), the final name will be luaopen_libnativefunc
I'm using lib as the file prefix because it is a good practice starting your lib names with lib
So let's start defining the function
Code: Select all
int luaopen_libnativefunc(lua_State* L)
Code: Select all
static const struct luaL_Reg nativeFuncLib []
Code: Select all
static const struct luaL_Reg nativeFuncLib [] =
{
{"mult50", l_mult50}, //Your function name, and the function reference after
{NULL, NULL}
}
Segmentation Fault (core dumped)
This is a default C error message when your iterator goes out from the array length
After that, in the same function, you will need to register your lib in Lua, this is where I got the most errors trying to find the correct one to use:
Code: Select all
luaL_register(L, "nativelib", nativeFuncLib)
nativelib["mult50"](), that's how it will work, for finishing it, just return 1, and now I will put all the code here for easier following:
Code: Select all
#include <lua.h>
#include <lauxlib.h>
static int l_mult50(lua_State* L)
{
double number = luaL_checknumber(L, 1);
lua_pushnumber(L, number*50);
return 1;
}
int luaopen_libnativefunc(lua_State* L)
{
static const struct luaL_Reg nativeFuncLib [] =
{
{"mult50", l_mult50}, //Your function name, and the function reference after
{NULL, NULL}
};
luaL_register(L, "nativelib", nativeFuncLib);
return 1;
}
After that, for using it on our Lua code, we will need to compile it as a Shared object, most know as library, .so or .dll files
For doing that, we will need to compile it with our new gcc command
Code: Select all
gcc -I/usr/include/lua5.1 nativefunc.c -c -fPIC
Code: Select all
gcc nativefunc.o -shared -o libnativefunc.so
After that, you will finally generate the file that you will import in Lua, for doing it there are 2 commons way, one being easier and less flexible, the other, the anthonym:
Easy way
Code: Select all
require "libnativefunc"
Code: Select all
lib = package.loadlib("./libnativefunc.so", "luaopen_libnativefunc")
lib();
--Shorter Version - package.loadlib("./libnativefunc.so", "luaopen_libnativefunc")()
After that, you will be able to call your own
Code: Select all
print(nativelib.mult50(50))