Page 1 of 2

Calling C dll from love2d

Posted: Sun Feb 02, 2020 10:29 pm
by PauloftheWest
I have a "it works fine in Linux, but fails in Windows" error that I think is really a "it happens to work in Linux, but never in Windows" issue.

Namely, I have library code for our game built into a .so/.dll using gcc (for both Linux and Windows.) Unfortunately, when I run in Windows I get a segfault when I attempt to register my C functions. Here is the first line in my main.lua:

Code: Select all

-- This loads the C library and binds is to a 'ds' object
ds = require 'libds'
In my .so/.dll I have:

Code: Select all

// How Lua registers the functions.
int luaopen_libds (lua_State *L){
    printf("Registering functions...\n");
    fflush(stdout);
    luaL_register(L, "libds", lslib);
    printf("Functions Registered.\n");
    fflush(stdout);
    return 1;
}
Naturally lslib is setup with the correct table of functions. The debugger tells me that the seg fault occurs on 'luaL_register'. I put printf in there to confirm. If I print out lua_State (the L), I get a non-null pointer. Again Linux works without issue...

From what I researched on the internet, I've noticed that if threads are used (which gdb reports Love2d is using) then the passed in lua_State may have a race condition with the garbage collection. A solution listed is to use only the global lua state when Lua was instantiated. Unfortunately, I don't know how to get it. Although, I don't know how this would happen as the thread should still be open...

Is there a love2d C function to get the global lua state? Maybe in a Love2d .dll? I noticed in lua 5.2 that there is a function call to get this, but we have 5.1.

Also, is there a way to run love2d in a single thread? It is annoying running a debugger and/or Valgrind on love2d...

Re: Calling C dll from love2d

Posted: Sun Feb 02, 2020 10:40 pm
by raidho36
This function have been removed from Lua 5.2, try using updated API.

Re: Calling C dll from love2d

Posted: Mon Feb 03, 2020 12:05 am
by PauloftheWest
Which function are you referring to? If I try to call any regular lua function on the passed in lua_State *L, I get a seg fault. Is there a different function beside the luaopen_* to use for interfacing with C? If so, what is it?

Re: Calling C dll from love2d

Posted: Mon Feb 03, 2020 12:41 am
by raidho36
I'm referring to the function that crashes your dll - luaL_register. There's a new method of registering C functions in 5.2. Consult the manual. https://www.lua.org/pil/26.html https://www.lua.org/manual/5.2/manual.html#4

Also I don't believe single-threaded LOVE is possible, because the audio module has hard-coded multithreading in it, and so does the entire OpenAL and SDL's input module I believe (I could be wrong) which is hard-coded to hook to the window module. You can try disabling audio, sound, window, joystick, keyboard, mouse, touch and thread modules - then it might run in a single threaded mode. At that point you should just use bare LuaJIT, which is single threaded by design.

Re: Calling C dll from love2d

Posted: Mon Feb 03, 2020 1:09 am
by PauloftheWest
I have tried the ones in (https://www.lua.org/pil/26.1.html) namely lua_pushcfunction, and lua_setglobal. I get the same seg fault. Happens on the first lua_* function I call. I've even tried lua_createtable just for the fun of it.

You are mentioning lua5.2. I was under the impression we are using lua 5.1. Has there been a change I missed? If so, I bet that is the issue.
https://love2d.org/forums/viewtopic.php?t=83356

I just redownloaded the Window's Love 11.3 zip file: it contain a lua51.dll. Is there a different dll I should use?

Re: Calling C dll from love2d

Posted: Mon Feb 03, 2020 1:16 am
by raidho36
LuaJIT is based on 5.1 specs with some 5.2 features backported, with little implementation details available; it's a special case. Then again it might be simply the case of building your DLL against Lua binaries and not LuaJIT ones.

Re: Calling C dll from love2d

Posted: Mon Feb 03, 2020 5:00 pm
by PauloftheWest
Do you know what compiler love2d is compiled with? I use mingw, maybe it is a compiler mismatch of some sort.

For compiling, I use the same headers for both Linux and Windows. As for the .dll I use the one supplied with love2d .zip file. I'll have to look at regular lua dll.

Re: Calling C dll from love2d

Posted: Mon Feb 03, 2020 5:16 pm
by slime
Official builds of LÖVE 11.x for Windows have been compiled with VS2013.

Re: Calling C dll from love2d

Posted: Wed Feb 05, 2020 2:00 am
by AuahDark
That's being said, mixing DLLs between different (MSVC) compiler can cause problems.

At first, I'd look at "lslib" variables. The luaL_reg should be terminated with {NULL, NULL} to indicate the end of functions to register, so.

Code: Select all

luaL_Reg lslib[] = {
    {"func1", func1},
    {"func2", func2},
    {NULL, NULL}
};

Re: Calling C dll from love2d

Posted: Thu Feb 06, 2020 2:13 am
by PauloftheWest
AuahDark, Thank you, but my lslib does have the sentinel.

My tests show that yes, you are correct, mixing the 64-bit mingw with 64-bit msvc causes issues. I found out on LuaJIT's site: http://luajit.org/install.html that LuaJit is NOT compatible with 64-bit mingw! Although, LuaJIT is compatible with with 32-bit mingw.

Once I switched to 32-bit (using the -m32 flag) the code compiled and ran as expected. So love2d 32-bit works with my setup when I switch to 32-bit binaries. Anyone reading this, keep in mind that it looks like you will need to use mscv if you want 64-bit C dll on Windows to work with love2d. (Although, I did not test this.)

I'm glad it isn't a threading issue...

Thank you everyone!