Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a C++ DLL loadable by Lua

Tags:

c++

c

dll

lua

I have a small app that uses Lua linked as dll (not static). I want to load my own c++-written dll via Lua using package.loadlib (libname, funcname). For this purpose I need to export a function that follows the Lua's lua_CFunction protocol. Clearly for that reason I have to incorporate lua.h into my project and use Lua's functions to pass parameters and results. So my questions are:

  1. Will my DLL use Lua dll that is already loaded into small app's process?
  2. Does package.loadlib load and unload my DLL immediately or my DLL once loaded remains until the end lua scrpit execution or application termination?
like image 409
Aoi Karasu Avatar asked Aug 26 '10 13:08

Aoi Karasu


1 Answers

Starting with your specific questions:

  1. Yes, but only if your DLL is implicitly linked to it. Be careful about this, because if you accidentally link two copies of the Lua VM into your application this can cause great confusion. For that matter, similar concerns apply to the C runtime as well. I would load the whole application under Dependency Walker to verify that it only refers to one instance of the Lua DLL and one single C runtime.

  2. My understanding is that package.loadlib() is only responsible for loading and linking to the named function in the named library. As long as the returned function object (representing the lua_CFunction you named) is alive, then the DLL is certainly loaded. If you loose the last reference to the function, then the library could be available for garbage collection, and if collected it will be unloaded. There has been talk on the Lua-L mailing list about exactly how to guarantee that a specific DLL got unloaded, if that is your concern. Otherwise, if you just assume the DLL is loaded as long as you can reach the function stored in it, you will be fine.

Let me add that the module system built on top of this is a much better way to extend Lua with C or C++ code. Chapter 26 of Programming in Lua describes this in more detail, and the link is to that chapter in the online copy of the first edition (which describes Lua 5.0). Note that the module system did change a little in Lua 5.1, and again in Lua 5.2. Obtaining a copy of the second or third editions of PiL (available in both paper and ebook form through many booksellers) may be helpful.

Here's an executive summary: To create a module named foo in C, you create foo.dll that exports at minimum a function with the prototype int luaopen_foo(lua_State *L). That function should load your module (typically by using luaL_register() in Lua 5.1, or luaL_newlib() or luaL_setfuncs() in Lua 5.2 to register a table full of C functions) and return that table. On the Lua side, you put the DLL somewhere on the path described in package.cpath, and then it can be loaded by code like local foo = require "foo". There are other subtle differences between the various Lua 5.x versions, but it is relatively straightforward to create C code that can be compiled for any of them.

Doing things this way, you have the advantage that the module can be loaded from a path, can be written in either C or Lua or a mix of both, and plays well with other modules. You also get to load as many or as few C functions as you need with a single invocation of require.

like image 164
RBerteig Avatar answered Nov 11 '22 10:11

RBerteig