diff --git a/vlib/dl/dl_nix.c.v b/vlib/dl/dl_nix.c.v index 080fcdd436..6b910005ab 100644 --- a/vlib/dl/dl_nix.c.v +++ b/vlib/dl/dl_nix.c.v @@ -2,18 +2,28 @@ module dl #include -fn C.dlopen(filename charptr, flags int) voidptr -fn C.dlsym(handle voidptr, symbol charptr) voidptr - pub const ( RTLD_NOW = C.RTLD_NOW - DL_EXT = '.so' + DL_EXT = '.so' ) +fn C.dlopen(filename charptr, flags int) voidptr + +fn C.dlsym(handle voidptr, symbol charptr) voidptr + +fn C.dlclose(handle voidptr) int + +// open loads the dynamic shared object. pub fn open(filename string, flags int) voidptr { return C.dlopen(filename.str, flags) } +// close frees a given shared object. +pub fn close(handle voidptr) bool { + return C.dlclose(handle) == 0 +} + +// sym returns an address of a symbol in a given shared object. pub fn sym(handle voidptr, symbol string) voidptr { return C.dlsym(handle, symbol.str) } diff --git a/vlib/dl/dl_test.v b/vlib/dl/dl_test.v index 7451ed81f2..ea292cc4d8 100644 --- a/vlib/dl/dl_test.v +++ b/vlib/dl/dl_test.v @@ -2,27 +2,45 @@ import dl fn test_dl() { $if linux { - run_test_linux() + run_test_invalid_lib_linux() return } $if windows { - run_test_windows() + run_test_invalid_lib_windows() + run_test_valid_lib_windows() + run_test_invalid_sym_windows() + run_test_valid_sym_windows() return } $else { eprint('currently not implemented on this platform') } } -fn run_test_linux() { +fn run_test_invalid_lib_linux() { // ensure a not-existing dl won't be loaded h := dl.open('not-existing-dynamic-link-library', dl.RTLD_NOW) - // println('handle = $h') assert h == 0 } -fn run_test_windows() { +fn run_test_invalid_lib_windows() { // ensure a not-existing dl won't be loaded h := dl.open('not-existing-dynamic-link-library', dl.RTLD_NOW) - // println('handle = $h') assert h == 0 } + +fn run_test_valid_lib_windows() { + h := dl.open('shell32', dl.RTLD_NOW) + assert h != 0 +} + +fn run_test_invalid_sym_windows() { + h := dl.open('shell32', dl.RTLD_NOW) + proc := dl.sym(h, 'CommandLineToArgvW2') + assert proc == 0 +} + +fn run_test_valid_sym_windows() { + h := dl.open('shell32', dl.RTLD_NOW) + proc := dl.sym(h, 'CommandLineToArgvW') + assert proc != 0 +} diff --git a/vlib/dl/dl_windows.c.v b/vlib/dl/dl_windows.c.v index d602bd1257..ec971447c2 100644 --- a/vlib/dl/dl_windows.c.v +++ b/vlib/dl/dl_windows.c.v @@ -2,17 +2,27 @@ module dl pub const ( RTLD_NOW = 0 - DL_EXT = '.dll' + DL_EXT = '.dll' ) -fn C.LoadLibraryA(libfilename byteptr) voidptr -fn C.GetProcAddress(handle voidptr, procname byteptr) voidptr +fn C.LoadLibrary(libfilename C.LPCWSTR) voidptr +fn C.GetProcAddress(handle voidptr, procname C.LPCSTR) voidptr + +fn C.FreeLibrary(handle voidptr) bool + +// open loads a given module into the address space of the calling process. pub fn open(filename string, flags int) voidptr { - res := C.LoadLibraryA(filename.str) + res := C.LoadLibrary(filename.to_wide()) return res } +// close frees the loaded a given module. +pub fn close(handle voidptr) bool { + return C.FreeLibrary(handle) +} + +// sym returns an address of an exported function or variable from a given module. pub fn sym(handle voidptr, symbol string) voidptr { return C.GetProcAddress(handle, symbol.str) }