diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/lua-interface-main.c | 97 |
2 files changed, 96 insertions, 3 deletions
@@ -223,7 +223,7 @@ lua-interface-gl.$(SHARED_EXT): $(ALL_OBJECTS) ln -sf $@ lua-interface.$(SHARED_EXT) lua-interface: lua-interface-mesa.$(SHARED_EXT) lua-interface-main.o - $(LD) -o $@ -L. lua-interface.$(SHARED_EXT) lua-interface-main.o + $(LD) -o $@ -ldl lua-interface-main.o lua-interface-dbg: $(ALL_OBJECTS) $(DEBUG_OBJECTS) $(LD) -o lua-interface-dbg $(ALL_OBJECTS) $(DEBUG_OBJECTS) $(LDFLAGS) $(LDFLAGS_MESA) -locci -lclntsh -lnnz11 ../lua-modules-iup/luaiup.a -lXm -lXpm -lXmu -lXt -lXext -lX11 -lm diff --git a/src/lua-interface-main.c b/src/lua-interface-main.c index 35579db..5c16ef5 100644 --- a/src/lua-interface-main.c +++ b/src/lua-interface-main.c @@ -1,5 +1,98 @@ -int dll_main(int argc, char ** argv); +#define MAX_PATH 1024 + +#include <stdio.h> +#include <string.h> + +#if defined(_WIN32) +#define SHARED_EXT "dll" +#elif defined(__APPLE__) +#define SHARED_EXT "dylib" +#else +#define SHARED_EXT "so" +#endif + +typedef void(*dll_main_t)(int argc, char ** argv); + +#if defined(_WIN32) +#include <windows.h> + +static void showError() { + DWORD dwErrCode = GetLastError(); + LPVOID lpMsgBuf; + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, 0, NULL )) { + fprintf(stderr, "Error: %s\n", lpMsgBuf); + LocalFree(lpMsgBuf); + } +} + +static HMODULE LoadLibraryExWrap(LPCTSTR lpFileName, HANDLE hFile, DWORD dwFlags) { + HMODULE r = LoadLibraryEx(lpFileName, hFile, dwFlags); + if (!r) + showError(); + return r; +} + +static dll_main_t LoadDllMain(const char * searchpath) { + HMODULE handle; + const char * fname = "lua-interface." SHARED_EXT; + + if (!(handle = LoadLibraryExWrap(fname, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) && + !(handle = LoadLibraryExWrap(fname, NULL, NULL))) { + LuaLoadPlugin(&Input(fname), L); + return NULL; + } + + dll_main_t dll_main = (dll_main) GetProcAddress(handle, "dll_main"); + + if (!dll_main) + FreeLibrary(handle); + + return dll_main; +} + +#else +#include <dlfcn.h> + +static dll_main_t LoadDllMain(const char * searchpath) { + const char * fname = "./lua-interface." SHARED_EXT; + void * handle = dlopen(fname, RTLD_NOW | RTLD_GLOBAL); + + if (!handle) { + char full_fname[MAX_PATH]; + strcpy(full_fname, searchpath); + strcat(full_fname, "lua-interface." SHARED_EXT); + handle = dlopen(full_fname, RTLD_NOW | RTLD_GLOBAL); + if (!handle) { + return NULL;; + } + } + + dll_main_t dll_main = (dll_main_t) dlsym(handle, "dll_main"); + + if (!dll_main) + dlclose(handle); + + return dll_main; +} + +#endif int main(int argc, char ** argv) { - dll_main(argc, argv); + char searchpath[MAX_PATH]; + char * slash; + strcpy(searchpath, argv[0]); + slash = strrchr(searchpath, '/'); + if (slash) { + *slash = 0; + } else { + searchpath[0] = 0; + } + dll_main_t dll_main = LoadDllMain(searchpath); + if (dll_main) + dll_main(argc, argv); } |