first version of loadlib for Mac OS X (not tested yet!!)

This commit is contained in:
Roberto Ierusalimschy 2004-10-07 14:27:20 -03:00
parent 5cb6037d49
commit 3bec76abe3
1 changed files with 66 additions and 22 deletions

View File

@ -1,29 +1,28 @@
/* /*
** $Id: loadlib.c,v 1.5 2003/05/14 21:01:53 roberto Exp roberto $ ** $Id: loadlib.c,v 1.6 2004/04/30 20:13:38 roberto Exp roberto $
** Dynamic library loader for Lua ** Dynamic library loader for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
* *
* This Lua library exports a single function, called loadlib, which is * This Lua library exports a single function, called loadlib, which
* called from Lua as loadlib(lib,init), where lib is the full name of the * is called from Lua as loadlib(lib,init), where lib is the full
* library to be loaded (including the complete path) and init is the name * name of the library to be loaded (including the complete path) and
* of a function to be called after the library is loaded. Typically, this * init is the name of a function to be called after the library is
* function will register other functions, thus making the complete library * loaded. Typically, this function will register other functions, thus
* available to Lua. The init function is *not* automatically called by * making the complete library available to Lua. The init function is
* loadlib. Instead, loadlib returns the init function as a Lua function * *not* automatically called by loadlib. Instead, loadlib returns the
* that the client can call when it thinks is appropriate. In the case of * init function as a Lua function that the client can call when it
* errors, loadlib returns nil and two strings describing the error. * thinks is appropriate. In the case of errors, loadlib returns nil and
* The first string is supplied by the operating system; it should be * two strings describing the error. The first string is supplied by
* informative and useful for error messages. The second string is "open", * the operating system; it should be informative and useful for error
* "init", or "absent" to identify the error and is meant to be used for * messages. The second string is "open", "init", or "absent" to identify
* making decisions without having to look into the first string (whose * the error and is meant to be used for making decisions without having
* format is system-dependent). * to look into the first string (whose format is system-dependent).
* * This module contains an implementation of loadlib for Unix systems
* This module contains an implementation of loadlib for Unix systems that * that have dlfcn, an implementation for Darwin (Mac OS X), an
* have dlfcn, an implementation for Windows, and a stub for other systems. * implementation for Windows, and a stub for other systems. See
* See the list at the end of this file for some links to available * the list at the end of this file for some links to available
* implementations of dlfcn and interfaces to other native dynamic loaders * implementations of dlfcn and interfaces to other native dynamic
* on top of which loadlib could be implemented. * loaders on top of which loadlib could be implemented.
*
*/ */
#define loadlib_c #define loadlib_c
@ -130,6 +129,51 @@ static int loadlib(lua_State *L)
#endif #endif
/* Native Mac OS X / Darwin Implementation */
#ifdef USE_DYLD
#define LOADLIB
#include <mach-o/dyld.h>
static int loadlib (lua_State *L) {
const char * err_str;
const char * err_file;
NSLinkEditErrors err;
int err_num;
const char *path=luaL_checkstring(L,1);
const char *init=luaL_checkstring(L,2);
const struct mach_header *lib;
/* this would be a rare case, but prevents crashing if it happens */
if(!_dyld_present()) {
lua_pushnil(L);
lua_pushstring(L,"dyld not present.");
lua_pushstring(L,"absent");
return 3;
}
lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
if(lib != NULL) {
NSSymbol init_sym = NSLookupSymbolInImage(lib, init,
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
if(init_sym != NULL) {
lua_CFunction f = (lua_CFunction)NSAddressOfSymbol(init_sym);
lua_pushlightuserdata(L,(void *)lib);
lua_pushcclosure(L,f,1);
return 1;
}
}
/* else an error ocurred */
NSLinkEditError(&err, &err_num, &err_file, &err_str);
lua_pushnil(L);
lua_pushstring(L, err_str);
lua_pushstring(L, (lib != NULL) ? "init" : "open");
/* Can't unload image */
return 3;
}
#endif
#ifndef LOADLIB #ifndef LOADLIB