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() {
|
||||
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)}')
|
||||
mut f := FNAdder(0)
|
||||
f = dl.sym(handle, 'add_1')
|
||||
f = dl.sym_opt(handle, 'add_1') ?
|
||||
eprintln('f: ${ptr_str(f)}')
|
||||
res := f(1, 2)
|
||||
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 {
|
||||
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.dlerror() charptr
|
||||
|
||||
// open loads the dynamic shared object.
|
||||
pub fn open(filename string, flags int) voidptr {
|
||||
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 {
|
||||
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 {
|
||||
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