Created
November 16, 2020 12:34
-
-
Save metab0t/f0cc1a908a557757c686ad79b3bddb32 to your computer and use it in GitHub Desktop.
Test Julia dlopen function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <direct.h> | |
#include <assert.h> | |
#include <stdio.h> | |
#define _OS_WINDOWS_ | |
int isabspath(const char *in) { | |
#ifdef _OS_WINDOWS_ | |
char c0 = in[0]; | |
if (c0 == '/' || c0 == '\\') { | |
return 1; // absolute path relative to %CD% (current drive), or UNC | |
} else if (c0 && in[1] == ':') { | |
char c2 = in[2]; | |
return c2 == '/' || c2 == '\\'; // absolute path with drive name | |
} | |
#else | |
if (in[0] == '/') | |
return 1; // absolute path | |
#endif | |
return 0; // relative path | |
} | |
#if defined(__APPLE__) | |
static char const *const extensions[] = {"", ".dylib"}; | |
#elif defined(_OS_WINDOWS_) | |
static char const *const extensions[] = {"", ".dll"}; | |
extern volatile int needsSymRefreshModuleList; | |
#else | |
static char const *const extensions[] = {"", ".so"}; | |
#endif | |
#define N_EXTENSIONS (sizeof(extensions) / sizeof(char *)) | |
static int endswith_extension(const char *path) { | |
if (!path) | |
return 0; | |
size_t len = strlen(path); | |
// Skip the first one since it is empty | |
for (size_t i = 1; i < N_EXTENSIONS; i++) { | |
const char *ext = extensions[i]; | |
size_t extlen = strlen(ext); | |
if (len < extlen) | |
return 0; | |
// Skip version extensions if present | |
size_t j = len - 1; | |
while (j > 0) { | |
if (path[j] == '.' || (path[j] >= '0' && path[j] <= '9')) | |
j--; | |
else | |
break; | |
} | |
if ((j == len - 1 || path[j + 1] == '.') && | |
memcmp(ext, path + j - extlen + 1, extlen) == 0) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
#define PATHBUF 4096 | |
#define JL_RTLD(flags, FLAG) (flags & JL_RTLD_##FLAG ? RTLD_##FLAG : 0) | |
#ifdef _OS_WINDOWS_ | |
static void win32_formatmessage(DWORD code, char *reason, int len) { | |
DWORD res; | |
LPWSTR errmsg; | |
res = FormatMessageW( | |
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | | |
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, | |
NULL, code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), | |
(LPWSTR)&errmsg, 0, NULL); | |
if (!res && (GetLastError() == ERROR_MUI_FILE_NOT_FOUND || | |
GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND)) { | |
res = FormatMessageW( | |
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | | |
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, | |
NULL, code, 0, (LPWSTR)&errmsg, 0, NULL); | |
} | |
res = WideCharToMultiByte(CP_UTF8, 0, errmsg, -1, reason, len, NULL, NULL); | |
assert(res > 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER); | |
reason[len - 1] = '\0'; | |
LocalFree(errmsg); | |
} | |
#endif | |
void *jl_dlopen(const char *filename, unsigned flags) { | |
#if defined(_OS_WINDOWS_) | |
size_t len = MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0); | |
if (!len) | |
return NULL; | |
WCHAR *wfilename = (WCHAR *)alloca(len * sizeof(WCHAR)); | |
if (!MultiByteToWideChar(CP_UTF8, 0, filename, -1, wfilename, len)) | |
return NULL; | |
HANDLE lib = LoadLibraryExW(wfilename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); | |
// if (lib) | |
// needsSymRefreshModuleList = 1; | |
return lib; | |
#else | |
dlerror(); /* Reset error status. */ | |
return dlopen(filename, (flags & JL_RTLD_NOW ? RTLD_NOW : RTLD_LAZY) | | |
JL_RTLD(flags, LOCAL) | JL_RTLD(flags, GLOBAL) | |
#ifdef RTLD_NODELETE | |
| JL_RTLD(flags, NODELETE) | |
#endif | |
#ifdef RTLD_NOLOAD | |
| JL_RTLD(flags, NOLOAD) | |
#endif | |
#if defined(RTLD_DEEPBIND) && \ | |
!(defined(JL_ASAN_ENABLED) || defined(JL_TSAN_ENABLED) || \ | |
defined(JL_MSAN_ENABLED)) | |
| JL_RTLD(flags, DEEPBIND) | |
#endif | |
#ifdef RTLD_FIRST | |
| JL_RTLD(flags, FIRST) | |
#endif | |
); | |
#endif | |
} | |
void *jl_load_dynamic_library(const char *modname, unsigned flags, | |
int throw_err) { | |
char path[PATHBUF], relocated[PATHBUF]; | |
int i; | |
#ifdef _OS_WINDOWS_ | |
int err; | |
#endif | |
void *handle; | |
int abspath; | |
// number of extensions to try — if modname already ends with the | |
// standard extension, then we don't try adding additional extensions | |
int n_extensions = endswith_extension(modname) ? 1 : N_EXTENSIONS; | |
abspath = isabspath(modname); | |
assert(abspath != 0); | |
// now fall back and look in default library paths, for all extensions | |
for (i = 0; i < n_extensions; i++) { | |
const char *ext = extensions[i]; | |
path[0] = '\0'; | |
snprintf(path, PATHBUF, "%s%s", modname, ext); | |
handle = jl_dlopen(path, flags); | |
if (handle) | |
goto done; | |
#ifdef _OS_WINDOWS_ | |
err = GetLastError(); | |
break; // LoadLibrary already tested the rest | |
#endif | |
} | |
notfound: | |
if (throw_err) { | |
#ifdef _OS_WINDOWS_ | |
char reason[256]; | |
win32_formatmessage(err, reason, sizeof(reason)); | |
#else | |
const char *reason = dlerror(); | |
#endif | |
#ifndef __clang_analyzer__ | |
// Hide the error throwing from the analyser since there isn't a way to | |
// express "safepoint only when throwing error" currently. | |
printf("could not load library \"%s\"\n%s", modname, reason); | |
#endif | |
} | |
handle = NULL; | |
done: | |
return handle; | |
} | |
int main(int argc, char const *argv[]) { | |
// write your path of dll | |
const char libname[] = "C:\\msys64\\home\\meta\\dist\\bin\\libcoinmumps-2.dll"; | |
int flags = 0; | |
int throw_error = 1; | |
void *handle = jl_load_dynamic_library(libname, flags, throw_error); | |
if (handle) { | |
printf("successful\n"); | |
} | |
done: | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function dlopen(s::AbstractString, flags::Integer=0; throw_error::Bool=true) | |
ret = ccall(:jl_load_dynamic_library, Ptr{Cvoid}, (Cstring, UInt32, Cint), s, flags, Cint(throw_error)) | |
if ret == C_NULL | |
return nothing | |
end | |
return ret | |
end | |
libname = "C:\\msys64\\home\\meta\\dist\\bin\\libcoinmumps-2.dll" | |
dlopen(libname) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment