LuaJIT FFI Binding issue

I also posted this on the forums, but it looks like Answers is probably here it should live.

I am wanting to use LuaJIT and it’s awesome ffi extension. Basically LuaJIT can bind to any exposed C function symbol in a binary.

So in C you can declare a function as such:

extern "C" __declspec(dllexport) void TestFunction();

The lua code to call this is really straight forward:

local ffi = require("ffi")

--The C function prototype.
ffi.cdef[[
void TestFunction();
]]

--Call the Function
ffi.C.TestFunction()

It’s pretty awesome. The Lua → C calling overhead is basically the same as a C → C call.

I’ve worked out the module loading system and have LuaJIT linked in to my Game module/dll, and can all and run lua code.

The problem is, ffi only searches for symbols in the executable by default. It needs to load my game dll to search it for symbols (this is done on windows with the LoadLibrary function behind the scenes). As the Compile function within the UEEditor rebuilds and hot loads your game dll with a random suffix this is a bit of a problem. The lua code becomes something like this:

local ffi = require("ffi")

ffi.cdef[[
void TestFunction();
]]

local gameLib = ffi.load("UE4Editor-AutomationGame-5749.dll")

gameLib.TestFunction()

So I need to get the currently used Game dll by the editor. Delving through and debugging the UBT, this suffix is appending quite late in the process. So there is no elegant way to getting the dll name and doing a bit of a hack where after the build it spits out the dll name in a file to lua to load. Lua has no native functions for file navigation either.

Another option, is I may be able to use ffi to call the various windows native FindFirstFile, FindNextFile etc and find the newest dll to load. But that is also a hack.

So ultimately I need to edit the Engines source to get the currently used dll name out via a simple C function that ffi can bind to. Does anyone know where about the LoadLibrary is called for your game?

Any other thoughts or options on this? I’m not hugely versed on how the symbols are loaded, but this seems to be the case in my experimentation. Cheers.

1 Like

I have this fairly worked out, not super happy with it but it seems to work. This is a windows only solution.

Using Psapi functions, loop through the modules loaded by the current process. The modules most recently loaded appear to be at the end of the list. UE4Editor seems to hold on to modules for a little while. So working backwards through the module list gets the most recent one.

bool ALuaController::GetGameModuleName()
{
	HANDLE currentProcess = GetCurrentProcess();

	HMODULE hMods[1024];
	::DWORD cbNeeded;

	if (EnumProcessModules(currentProcess, hMods, sizeof(hMods), &cbNeeded))
	{
		unsigned int moduleCount = cbNeeded / sizeof(HMODULE);

		for (unsigned int i = moduleCount; i > 0; i--) //Need the last loaded module
		{
			char szFileName[1024];

			if (GetModuleFileNameExA(currentProcess, hMods[i], szFileName, 1024))
			{
				if (strstr(szFileName, "UE4Editor-AutomationGame"))
				{
					strcpy_s(m_szGameModuleName, szFileName); 

					for (unsigned c = 0; c < strlen(m_szGameModuleName); c++)
					{
						if (m_szGameModuleName[c] == '\\')
						{
							m_szGameModuleName[c] = '/';
						}
					}

					return true;
				}
			}
		}
	}

	return false;
}