tags:

views:

121

answers:

2

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?
A: 

You can dynamically link to the same Lua dll as in your application.

As for package.loadlib, I have no idea how that works. Read the source ?

DeadMG
+5  A: 

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. Note that the module system did change a little bit after the online version was written, so finding a copy of the second edition 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() 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 the function call require "foo".

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.

RBerteig
Thank you very much for great answer. It helped me a lot! Apart from Lua functionality I want my DLL to hook to application's WndProc and add my custom toolbar so I don't want my DLL to unloaded under circumstances that I am unaware of.
AOI Karasu
You can gain some explicit control over its lifetime by holding your own additional reference to it, which you only release when you are ready. You can use `luaL_ref()` with the table at `LUA_REGISTRYINDEX` to take a reference to any object that can be held (in the form of an integer) on the C side, and released with `luaL_unref()`.
RBerteig