Felk
Felk

Reputation: 8224

add luasocket to program (bizhawk) shipped with own lua environment

I am trying to get luasocket working in the lua scripting environment of Bizhawk, but so far without luck. I downloaded the vc8 version of luasocket here, made sure I have vc8 installed, and checked the lua version that came with bizhawk: 5.1

But, when I start the script I get the following error:

LuaInterface.LuaScriptException: error loading module 'socket.core' from file './libs/socket\core.dll':
    Das angegebene Modul wurde nicht gefunden. (the given module was not found)

The lua code:

package.path = package.path..';./libs/lua/?.lua'
package.cpath = package.cpath..';./libs/?.dll'
local socket = require("socket")

The file system structure:

libs
   > lua
       > socket
            ftp.lua http.lua smtp.lua tp.lua url.lua
       ltn12.lua
       mime.lua
       socket.lua
   > socket
       core.dll
   > mime
       core.dll

It seems to find the files, because when I had the file structure wrong it gave me actual file-not-found errors. My best guess is that there is some kind if incompatibility between the lua that is shipped with Bizhawk and the external luasocket library binaries, but I am out of ideas.

Upvotes: 4

Views: 3394

Answers (2)

Paul Kulchenko
Paul Kulchenko

Reputation: 26754

I suspect that it's because of the dependence on lua51.dll. luasocket core.dll library is linked against lua51.dll (most likely; you can ran depends or similar tool to find out for sure), which is probably not present and this prevents socket.core from being loaded.

Even if you find lua51.dll, it's not likely to work if Bizhawk is statically compiled with lua51.dll as this will lead to two interpreters loaded into the same process, which is a recipe for seg faults.

There are three main options, but they all depend on how Bizhawk project is structured:

  1. Bizhawk is compiled against lua51.dll (and this dll is present as a standalone file). In this case you need to make sure that the socket/core.dll you are using is compiled against the same library and it should work (as long as the run-times are the same and lua51.sll is available in PATH).
  2. Bizhawk is statically compiled with lua51.dll. The simplest option is also statically compile luasocket libraries into the executable.
  3. If option 2 is not available, then you need to use a proxy library and export Lua symbols from the Bizhawk executable as described in this SO answer: https://stackoverflow.com/a/28310666/1442917

If none of this helps you to solve the problem, you'll need to get depends for your Windows platform and run it in the "profiling" mode, which will tell you the exact error that happens when that DLL is loaded.

Upvotes: 1

zeromus
zeromus

Reputation: 1667

This guy's set it up: https://github.com/antogerva/emuHostUDP (dearchive to emuhawk.exe base directory). His example seems to work, but it might not contain everything you need. Like HTTP for example.

Since project is complex and the luasockets examples are awful, here's a one-liner for testing http:

print(require("socket.http").request{ url = "http://www.google.com" });

Following his model, I applied the following method: contents of lua dir to root; lua5.1.dll to root. Note that we will not be using the core.dlls from luasockets. This is because BizHawk now has them integrated; and this was necessary to work around a bug with luasockets in bizhawk.

More specifically, we have

  • /emuhawk.exe
  • /Lua (untouched)
  • /Socket/ftp.lua,http.lua,etc.
  • /ltn12.lua,socket.lua,mime.lua
  • /lua5.1.dll
  • /mytest.lua

(with files from http://files.luaforge.net/releases/luasocket/luasocket/luasocket-2.0.2/luasocket-2.0.2-lua-5.1.2-Win32-vc8.zip)

I can't say why precisely all of this is necessary, but I think it's miraculous that it works, given that we have a customized lua.

When using lua, if you find a directory structure that works, it's best not to wrestle with it any further.

Update: (may be out of date) As soon as you do something nontrivial you may find bizhawk crashes. It seems this is due to a conflict with luasocket's "protection" system. Inspect http.lua and observe the code at the end which sends a function through socket.protect to wrap it. Remove the socket.protect wrapper and it should solve this problem.

Upvotes: 5

Related Questions