2
votes

So I wrote a little .dll with C++, in Visual Studio 2017. All it does is export a function which I call from a lua script. The lua script runs in an third party application; I want to extend its functionality with this library. I have to use package.loadlib because require is modified and only allows to load .lua files. (I confirmed that it does find .dll files, so its nothing with the package pathing)

#include "lua.hpp"

extern "C" __declspec(dllexport) int test(lua_State* L) {
  // luaL_checknumber(L, 1); // access violation
  // lua_pushnumber(L, 123); // freeze
  return 1;
}

I load this function using this code:

test, err = package.loadlib(dllpath, "test")

print("test = ", test, "err = ", err)
print("test() = ", test())
print("done")

that prints

test = function: 001D168B err = nil

test() = function: 001D168B

done

as expected...

But when I make the library call either lua function the application either permanently freezes or gets an access violation. lua_push* functions cause these freezes, while luaL_check* functions cause access violations.

I use Windows 10 (x64), the application is 32 bit, my .dll is compiled as 32 bit and both have the exact same lua version.

What am I doing wrong?

EDIT:

I was indeed linking wrong. I linked against lua5.3.lib when it should have been lua5.3-static.lib. I did not know that. It is working now.

1
Are you sure you're using the same lua library as the application is? - user253751
I know that the application uses 5.3.1 like my dll. - TheElderScroller
How did you link against the Lua DLL? Does your application provide an import library (.lib) for its Lua DLL? Or did you generate one from the DLL? Or did you use one from a different Lua distribution? - Doub
@Doub My DLL is build with the source found on lua.org. Else there is no linking. It's just a DLL which exports one function called "test", which I load with a lua script in the application. I don't have more access to this application than writing lua scripts for it. - TheElderScroller

1 Answers

0
votes

Having the exact same Lua version is not enough. It is very common for applications, especially games, to modify the Lua interpreter. But even if you had identical source code, it wouldn't work to have two copies of the compiled Lua C code (one in the game, one in your DLL) working together in the same program. This is because that C code uses global variables, and because there are two copies they are not in sync and it causes problems.

So if you want to call lua_pushstring, you need to find the address of that function inside the game. If the game was built with Lua in a DLL, find that DLL, and check with Dependency Walker that the symbols are exported correctly. Otherwise look at the game EXE in Dependency Walker, as an EXE can also export symbols. Once you've found a module (DLL or EXE) that export the Lua C API, you can generate a .lib from that module, and then link to it in your own DLL (that should not contain the Lua code itself).