/* * Open a shared object * Expecting 'full_name' as an UTF-8 string. */ int erts_sys_ddll_open(const char *full_name, void **handle, ErtsSysDdllError* err) { HINSTANCE hinstance; int len; wchar_t* wcp; Sint used; int code; if ((len = sys_strlen(full_name)) >= MAXPATHLEN - EXT_LEN) { if (err != NULL) { err->str = "Library name too long"; } return ERL_DE_LOAD_ERROR_NAME_TO_LONG; } wcp = (wchar_t*)erts_convert_filename_to_wchar((byte*)full_name, len, NULL, 0, ERTS_ALC_T_TMP, &used, EXT_LEN); wcscpy(&wcp[used/2 - 1], FILE_EXT_WCHAR); if ((hinstance = LoadLibraryW(wcp)) == NULL) { code = ERL_DE_DYNAMIC_ERROR_OFFSET - GetLastError(); if (err != NULL) { err->str = erts_sys_ddll_error(code); } } else { code = ERL_DE_NO_ERROR; *handle = (void *) hinstance; } erts_free(ERTS_ALC_T_TMP, wcp); return code; }
/* * Close a chared object */ int erts_sys_ddll_close2(void *handle, ErtsSysDdllError* err) { if (!FreeLibrary((HINSTANCE) handle)) { int code = ERL_DE_DYNAMIC_ERROR_OFFSET - GetLastError(); if (err != NULL) { err->str = erts_sys_ddll_error(code); } return code; } return ERL_DE_NO_ERROR; }
/* * Find a symbol in the shared object */ int erts_sys_ddll_sym2(void *handle, const char *func_name, void **function, ErtsSysDdllError* err) { FARPROC proc; if ((proc = GetProcAddress( (HINSTANCE) handle, func_name)) == NULL) { int code = ERL_DE_DYNAMIC_ERROR_OFFSET - GetLastError(); if (err != NULL) { err->str = erts_sys_ddll_error(code); } return code; } *function = (void *) proc; return ERL_DE_NO_ERROR; }
int erts_sys_ddll_open_noext(char *dlname, void **handle, ErtsSysDdllError* err) { HINSTANCE hinstance; if ((hinstance = LoadLibrary(dlname)) == NULL) { int code = ERL_DE_DYNAMIC_ERROR_OFFSET - GetLastError(); if (err != NULL) { err->str = erts_sys_ddll_error(code); } return code; } else { *handle = (void *) hinstance; return ERL_DE_NO_ERROR; } }
char *erts_ddll_error(int code) { switch (code) { case ERL_DE_NO_ERROR: return "No error"; case ERL_DE_LOAD_ERROR_NO_INIT: return "No driver init in dynamic library"; case ERL_DE_LOAD_ERROR_FAILED_INIT: return "Driver init failed"; case ERL_DE_LOAD_ERROR_BAD_NAME: return "Bad driver name"; case ERL_DE_LOAD_ERROR_NAME_TO_LONG: return "Driver name to long"; case ERL_DE_LOAD_ERROR_INCORRECT_VERSION: return "Driver compiled with incorrect version of erl_driver.h"; case ERL_DE_ERROR_NO_DDLL_FUNCTIONALITY: return "DDLL functionality not available on this platform"; case ERL_DE_ERROR_UNSPECIFIED: return "Unspecified dynamic library error"; case ERL_DE_LOOKUP_ERROR_NOT_FOUND: return "Symbol not found in dynamic library"; default: return erts_sys_ddll_error(code); } }