I'm still trying to get my head around Alien...looks like something that could open some pretty huge doors. I got a funny error message at one point when fooling around:
gtkMsgBox.lua:11: bad argument #1 to 'tostring' (userdata expected, got userdata)
One of my systems has Gtk2 installed in /opt, so the alien.load function in the gtk test doesn't work since it uses a full path to the file. Removing "/usr/lib" (using just the name of the library) fixed it.
Using full paths was never a good idea.
I've been trying to find out if alien can supply a list of functions available in a given library, but haven't had much luck so far. When making changes to the gtk test I eventually got something, but it doesn't look like gtk functions. I'm just poking at it for now.
local gtk,p,i=alien.load("libgtk-x11-2.0.so.0"),"pointer","int"
gtk_tab=getmetatable(gtk)
for i,v in pairs(gtk_tab) do
gtk_tab2=getmetatable(i) end
for i,v in pairs(gtk_tab2.__index) do print(i,v,type(v)) end
This is not possible. So you can stop trying ;-)
I think you a wrong idea how the dynamic loader works. You could compare the binary format (ELF) with a small database, with multiple indexes. When you start a program the kernel creates a new address space and the loader maps the program into that address space (actually the program and the libraries are not loaded, they are only mapped. Only when a page of memory has to be accessed then it gets loaded from the disk. This is called demand paging. Also multiple programs and libraries that reference the same files on disk share the same physical memory pages. A system can therefore load hundreds or thousands of huge programs with a ton of dependencies. But since most of the programs have the same dependencies and not all functions are always called, the actual physical memory consumption could be pretty low) The loader/linker then parses the ELF headers for external symbols which have to be resolved. It also parses a section with a list of external libraries it has to check. The linker then checks the external libraries for the needed symbols and maps them (the libraries) also into the address space of the program. After the libraries have been mapped into the address space, the linker knows the position (memory address) of the symbols and can replace the stubs in the program with the actual address.
This is called relocation.
Of course only the symbols that are used get relocated. So a program that links against a library doesn't know about the other symbols. For that it has to parse the library headers.
In this case it is even a little bit more complicated. murgaLua isn't linked against libgtk.so. At startup time the linker/loader doesn't even know about the libgtk dependency. In this case alien uses a special functionality of the loader. The dlopen, dlsym functions of the loader. It allows a program to load a library (the loader just maps it into the address space) and then search for a symbol in that library (dlsym takes a string of the symbol name and returns just the memory address of that symbol). This is what alien uses when you use a C function from a library.
While gtk=alien.load("libgtk.so"); gtk_window_new=gtk.gtk_window_new would suggest that all function names are in a gtk table, this isn't the case. alien just uses the __index method in the metatable to fake such a table. It just uses the string of the entry name to look up the symbol with dlsym.
If you want to have a list of all the exported symbols from a library you can use the nm or readelf tools that come with the GNU binutils:
[nm -g -D /usr/lib/libgtk.so | grep '^[0-9A-F]\{8\}\ T\ .*$'
readelf -s /usr/lib/libgtk.so | grep -v UND