#include #include #if defined(_WIN32) #define SHARED_EXT "dll" #elif defined(__APPLE__) #define SHARED_EXT "dylib" #else #define SHARED_EXT "so" #endif typedef void(*init_ptr_t)(Lua *); #if defined(_WIN32) #include #include "MemoryModule.h" void LuaLoadPlugin(const String & _fname, Lua * L) throw (GeneralException) { HMODULE handle; String fname = _fname + "." SHARED_EXT; Base::printm(M_INFO, "Loading library " + fname + "\n"); if (!(handle = LoadLibraryEx(fname.to_charp(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) && !(handle = LoadLibraryEx(fname.to_charp(), NULL, NULL))) { LuaLoadPlugin(&Input(fname), L); return; } init_ptr_t init_ptr = (init_ptr_t) GetProcAddress(handle, "init_plugin"); if (!init_ptr) { FreeLibrary(handle); throw GeneralException("No init pointer on plugin " + fname); } Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr); init_ptr(L); } void LuaLoadPlugin(Handle * h, Lua * L) throw (GeneralException) { Byte * buffer; buffer = (Byte *) malloc(h->GetSize()); h->read(buffer, h->GetSize()); HMEMORYMODULE module; if (!(module = MemoryLoadLibrary(buffer))) throw("Can't load library " + h->GetName() + " from memory."); init_ptr_t init_ptr = (init_ptr_t) MemoryGetProcAddress(module, "init_plugin"); if (!init_ptr) { MemoryFreeLibrary(module); throw GeneralException("No init pointer on plugin " + h->GetName()); } Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr); init_ptr(L); free(buffer); } #else #include void LuaLoadPlugin(const String & fname, Lua * L) throw (GeneralException) { String full_fname = "./" + fname + "." SHARED_EXT; void * handle = dlopen(full_fname.to_charp(), RTLD_NOW | RTLD_GLOBAL); Base::printm(M_INFO, "Loading library " + fname + "\n"); if (!handle) { LuaLoadPlugin(&Input(full_fname), L); return; } init_ptr_t init_ptr = (init_ptr_t) dlsym(handle, "init_plugin"); if (!init_ptr) { dlclose(handle); throw GeneralException("No init pointer on plugin " + fname); } Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr); init_ptr(L); } #if defined(__APPLE__) #include #include #include void LuaLoadPlugin(Handle * h, Lua * L) throw (GeneralException) { Byte * buffer; NSObjectFileImage image; kern_return_t result = vm_allocate(mach_task_self(), (vm_address_t *) &buffer, h->GetSize(), VM_FLAGS_ANYWHERE); h->read(buffer, h->GetSize()); if (NSCreateObjectFileImageFromMemory(buffer, h->GetSize(), &image) != NSObjectFileImageSuccess) throw("Can't load library " + h->GetName() + " from memory."); NSModule module; if (!(module = NSLinkModule(image, h->GetName().to_charp(), NSLINKMODULE_OPTION_PRIVATE))) throw("Can't link library " + h->GetName() + " from memory."); NSSymbol symbol = NSLookupSymbolInModule(module, "init_plugin"); init_ptr_t init_ptr = (init_ptr_t) NSAddressOfSymbol(symbol); if (!init_ptr) { NSDestroyObjectFileImage(image); throw GeneralException("No init pointer on plugin " + h->GetName()); } Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr); init_ptr(L); } #else #include // I don't know of any good way of doing this under linux except this one... *shrug* void LuaLoadPlugin(Handle * h, Lua * L) throw (GeneralException) { char ftemplate[] = "/tmp/luaplugin.so.XXXXXX"; int hdl; if ((hdl = mkstemp(ftemplate)) == -1) throw GeneralException("Can't create temporary file to load plugin " + h->GetName()); Byte * buffer; buffer = (Byte *) malloc(h->GetSize()); h->read(buffer, h->GetSize()); if (write(hdl, buffer, h->GetSize()) != h->GetSize()) { free(buffer); close(hdl); unlink(ftemplate); throw GeneralException("Couldn't write to temporary file."); } free(buffer); void * handle = dlopen(ftemplate, RTLD_NOW | RTLD_GLOBAL); unlink(ftemplate); close(hdl); Base::printm(M_INFO, "Loading library " + h->GetName() + "\n"); if (!handle) throw("Can't load library " + h->GetName() + " from memory."); init_ptr_t init_ptr = (init_ptr_t) dlsym(handle, "init_plugin"); if (!init_ptr) { dlclose(handle); throw GeneralException("No init pointer on plugin " + h->GetName()); } Base::printm(M_INFO, "Library loaded, init ptr = %p\n", init_ptr); init_ptr(L); } #endif #endif