lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Well, this is the version of loadlib that compiles on MacOS X without any need
for the dlcompat library. It seems to work just like the dlcompat version
does, and I can now load the modules I was having trouble with before -- it
was my own stupid fault. I was declaring functions static. Serves me right for
copy/pasting code.

I've got linking working now against shared objects. I compile my shared
object with the following options:

  gcc -undefined suppress -flat_namespace -bundle -o module.so module.o

Another way to do it is this:

  gcc -bundle_loader /opt/local/bin/lua -bundle -o module.so module.o

But that only works if the lua binary hasn't been stripped. The first form
always works.
#ifdef USE_DYLD
#define LOADLIB
#include <mach-o/dyld.h>
#include <stdlib.h> // malloc
#include <string.h> // strlen

static int loadlib(lua_State *L)
{
	const char *path=luaL_checkstring(L,1);
	const char *init=luaL_checkstring(L,2);

	NSObjectFileImage image;
	NSModule module = NULL;
	NSObjectFileImageReturnCode res;
	NSSymbol sym;
	char *symname;

	res = NSCreateObjectFileImageFromFile(path, &image);
	if (res != NSObjectFileImageSuccess)
	{
		lua_pushnil(L);
		switch (res)
		{
			case NSObjectFileImageFailure:
				lua_pushstring(L,"Unknown error.");
				break;
			case NSObjectFileImageInappropriateFile:
				lua_pushstring(L,"File is invalid type.");
				break;
			case NSObjectFileImageArch:
				lua_pushstring(L,"File is for wrong CPU architecture.");
				break;
			case NSObjectFileImageFormat:
				lua_pushstring(L,"File does not appear to be a Mach-O file.");
				break;
			case NSObjectFileImageAccess:
				lua_pushstring(L,"Permission denied.");
				break;
			default:
				lua_pushstring(L,"Unknown error.");
		}
		lua_pushstring(L,"open");
		return 3;
	}

	module = NSLinkModule(image, path, NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_RETURN_ON_ERROR);

	if (module == NULL)
	{
		NSLinkEditErrors dylderr;
		int dylderrno;
		const char *dyldfile;
		const char *errstr;
		NSLinkEditError(&dylderr, &dylderrno, &dyldfile, &errstr);

		lua_pushnil(L);
		lua_pushstring(L,errstr);
		lua_pushstring(L,"init");
		return 3;
	}

	NSDestroyObjectFileImage(image);

	symname = (char *)malloc(sizeof(char)*(strlen(init)+2));
	sprintf(symname, "_%s", init);
	sym = NSLookupSymbolInModule(module, symname);
	if (sym == NULL)
	{
		lua_pushnil(L);
		lua_pushstring(L,symname);
		lua_pushstring(L,"init");
		return 3;
	}
	free(symname);

	lua_pushlightuserdata(L, module);
	lua_pushcfunction(L, NSAddressOfSymbol(sym));
	return 2;
} 
#endif