Reputation: 31
I'm trying to create a Lua dll extension on Windows. I'm using Lua 5.3. My compiler is from MinGW and is gcc 4.9.3.
My C code for the dll extension is something like this:
#include <stdio.h>
#include <lua.h>
static int dub(lua_State *L) {
const double a = lua_tonumber(L, 1);
lua_pushnumber(L, a*2);
return 1;
}
__declspec(dllexport) int __cdecl luaopen_mylib(lua_State *L){
printf("One\n");
lua_pushcfunction(L, dub);
printf("Two\n");
lua_setglobal(L, "dub");
printf("Three\n");
return 1;
}
I'm compiling my dll like this:
gcc mylib.c -shared -o mylib.dll -llua
The idea being that I can load it from Lua and use it like this:
require "mylib"
print (dub(5)) --should print 10
However, when I actually try to run the Lua code, it crashes on the require "mylib"
line. The DLL is able to print "One" and "Two", but it does not get to print "Three" before it crashes. This tells me the problem may be with the 'lua_setglobal' call.
What's going wrong? How to I debug it further or fix it?
As a bonus question: what should the return value of luaopen_mylib be?
Thanks!
Upvotes: 3
Views: 540
Reputation: 21
I compiled your code and it works fine. So your problem isn't from your code. My guess is that you're using different versions of Lua, or the linking is somehow going wrong.
There are three places a version mismatch could occur.
#include <lua.h>
line-llua
lua
executableIt is vital that all three of these be the same lua version. If one is mismatched, that could cause the problem you're having. I would guess that your lua executable version doesn't match the others.
One other thing to try, is that your dll should link against the lua dll. There should be a file on your system called lua53.dll
. Copy it to your build directory. When you compile with gcc
, try this instead:
gcc mylib.c -shared -o mylib.dll lua53.dll
This means that your dll extension calls the exact same lua code that the lua executable is using. They way you have it now, with the -llua
line, it appears that you are linking in lua statically. This is almost never what you want for a dll library, because the lua executable will be calling code in lua53.dll
while your dll is calling separate code in the static library. I don't think this alone is causing your crash, but it's not good practice. If lua used global state (it doesn't), this linking issue could certainly cause your crash. Also, if you compile against lua53.dll
you'll find that mylib.dll
is much smaller.
In summary, I think you have a lua version mismatch somewhere that is causing your crash. You should also link against the lua dll instead of the static library for good form.
As a bonus question: what should the return value of luaopen_mylib be?
In your code it should actually be 0
instead of 1
as you have. The return value is the number of things left on the stack that you want the require()
call to return. Your library is just shoving itself into the global state and not returning any lua values. An alternative way to do things is to return a table with the library's functions in it. That way you don't pollute global state. Since your library has only one function, you could return it directly like this:
__declspec(dllexport) int __cdecl luaopen_mylib(lua_State *L){
lua_pushcfunction(L, dub);
return 1;
}
Then you use it from lua as:
local dub = require("mylib")
print (dub(5)) --should print 10
I prefer this way since the caller can decided what to name the imports and it doesn't pollute global space.
Upvotes: 2