dl: add dl.open_opt/2, dl.sym_opt/2 and dl.dlerror/0 utility functions
parent
0bde55f77e
commit
9e48826bcb
|
@ -7,10 +7,10 @@ type FNAdder = fn (int, int) int
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
library_file_path := os.join_path(os.getwd(), dl.get_libname('library'))
|
library_file_path := os.join_path(os.getwd(), dl.get_libname('library'))
|
||||||
handle := dl.open(library_file_path, dl.rtld_lazy)
|
handle := dl.open_opt(library_file_path, dl.rtld_lazy) ?
|
||||||
eprintln('handle: ${ptr_str(handle)}')
|
eprintln('handle: ${ptr_str(handle)}')
|
||||||
mut f := FNAdder(0)
|
mut f := FNAdder(0)
|
||||||
f = dl.sym(handle, 'add_1')
|
f = dl.sym_opt(handle, 'add_1') ?
|
||||||
eprintln('f: ${ptr_str(f)}')
|
eprintln('f: ${ptr_str(f)}')
|
||||||
res := f(1, 2)
|
res := f(1, 2)
|
||||||
eprintln('res: $res')
|
eprintln('res: $res')
|
||||||
|
|
22
vlib/dl/dl.v
22
vlib/dl/dl.v
|
@ -24,3 +24,25 @@ pub fn get_shared_library_extension() string {
|
||||||
pub fn get_libname(libname string) string {
|
pub fn get_libname(libname string) string {
|
||||||
return '$libname$dl.dl_ext'
|
return '$libname$dl.dl_ext'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// open_opt - loads the dynamic shared object.
|
||||||
|
// Unlike open, open_opt return an option.
|
||||||
|
pub fn open_opt(filename string, flags int) ?voidptr {
|
||||||
|
shared_object_handle := open(filename, flags)
|
||||||
|
if shared_object_handle == 0 {
|
||||||
|
e := dlerror()
|
||||||
|
return error(e)
|
||||||
|
}
|
||||||
|
return shared_object_handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// sym_opt returns the address of a symbol in a given shared object, if found.
|
||||||
|
// Unlike sym, sym_opt returns an option.
|
||||||
|
pub fn sym_opt(shared_object_handle voidptr, symbol string) ?voidptr {
|
||||||
|
sym_handle := sym(shared_object_handle, symbol)
|
||||||
|
if sym_handle == 0 {
|
||||||
|
e := dlerror()
|
||||||
|
return error(e)
|
||||||
|
}
|
||||||
|
return sym_handle
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ fn C.dlsym(handle voidptr, symbol charptr) voidptr
|
||||||
|
|
||||||
fn C.dlclose(handle voidptr) int
|
fn C.dlclose(handle voidptr) int
|
||||||
|
|
||||||
|
fn C.dlerror() charptr
|
||||||
|
|
||||||
// open loads the dynamic shared object.
|
// 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(charptr(filename.str), flags)
|
return C.dlopen(charptr(filename.str), flags)
|
||||||
|
@ -27,3 +29,11 @@ pub fn close(handle voidptr) bool {
|
||||||
pub fn sym(handle voidptr, symbol string) voidptr {
|
pub fn sym(handle voidptr, symbol string) voidptr {
|
||||||
return C.dlsym(handle, charptr(symbol.str))
|
return C.dlsym(handle, charptr(symbol.str))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dlerror provides a text error diagnostic message for functions in `dl`
|
||||||
|
// it returns a human-readable string, describing the most recent error
|
||||||
|
// that occurred from a call to one of the `dl` functions, since the last
|
||||||
|
// call to dlerror()
|
||||||
|
pub fn dlerror() string {
|
||||||
|
return unsafe { cstring_to_vstring(byteptr(C.dlerror())) }
|
||||||
|
}
|
||||||
|
|
|
@ -26,3 +26,14 @@ pub fn close(handle voidptr) bool {
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dlerror provides a text error diagnostic message for functions in `dl`
|
||||||
|
// it returns a human-readable string, describing the most recent error
|
||||||
|
// that occurred from a call to one of the `dl` functions, since the last
|
||||||
|
// call to dlerror()
|
||||||
|
pub fn dlerror() string {
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror
|
||||||
|
// Unlike dlerror(), GetLastError returns just an error code, that is function specific.
|
||||||
|
cerr := int(C.GetLastError())
|
||||||
|
return 'error code $cerr'
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue