dl: improve module
parent
e5ae4b6454
commit
54d1a29267
|
@ -2,18 +2,28 @@ module dl
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
fn C.dlopen(filename charptr, flags int) voidptr
|
|
||||||
fn C.dlsym(handle voidptr, symbol charptr) voidptr
|
|
||||||
|
|
||||||
pub const (
|
pub const (
|
||||||
RTLD_NOW = C.RTLD_NOW
|
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 {
|
pub fn open(filename string, flags int) voidptr {
|
||||||
return C.dlopen(filename.str, flags)
|
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 {
|
pub fn sym(handle voidptr, symbol string) voidptr {
|
||||||
return C.dlsym(handle, symbol.str)
|
return C.dlsym(handle, symbol.str)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,27 +2,45 @@ import dl
|
||||||
|
|
||||||
fn test_dl() {
|
fn test_dl() {
|
||||||
$if linux {
|
$if linux {
|
||||||
run_test_linux()
|
run_test_invalid_lib_linux()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
$if windows {
|
$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
|
return
|
||||||
} $else {
|
} $else {
|
||||||
eprint('currently not implemented on this platform')
|
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
|
// ensure a not-existing dl won't be loaded
|
||||||
h := dl.open('not-existing-dynamic-link-library', dl.RTLD_NOW)
|
h := dl.open('not-existing-dynamic-link-library', dl.RTLD_NOW)
|
||||||
// println('handle = $h')
|
|
||||||
assert h == 0
|
assert h == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_test_windows() {
|
fn run_test_invalid_lib_windows() {
|
||||||
// ensure a not-existing dl won't be loaded
|
// ensure a not-existing dl won't be loaded
|
||||||
h := dl.open('not-existing-dynamic-link-library', dl.RTLD_NOW)
|
h := dl.open('not-existing-dynamic-link-library', dl.RTLD_NOW)
|
||||||
// println('handle = $h')
|
|
||||||
assert h == 0
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -5,14 +5,24 @@ pub const (
|
||||||
DL_EXT = '.dll'
|
DL_EXT = '.dll'
|
||||||
)
|
)
|
||||||
|
|
||||||
fn C.LoadLibraryA(libfilename byteptr) voidptr
|
fn C.LoadLibrary(libfilename C.LPCWSTR) voidptr
|
||||||
fn C.GetProcAddress(handle voidptr, procname byteptr) 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 {
|
pub fn open(filename string, flags int) voidptr {
|
||||||
res := C.LoadLibraryA(filename.str)
|
res := C.LoadLibrary(filename.to_wide())
|
||||||
return res
|
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 {
|
pub fn sym(handle voidptr, symbol string) voidptr {
|
||||||
return C.GetProcAddress(handle, symbol.str)
|
return C.GetProcAddress(handle, symbol.str)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue