Browse Source

Merge pull request #3072 from laytan/add-dynlib-last_error

dynlib: add last_error procedure
Jeroen van Rijn 1 year ago
parent
commit
2784e8ea51
4 changed files with 33 additions and 2 deletions
  1. 17 2
      core/dynlib/lib.odin
  2. 4 0
      core/dynlib/lib_js.odin
  3. 5 0
      core/dynlib/lib_unix.odin
  4. 7 0
      core/dynlib/lib_windows.odin

+ 17 - 2
core/dynlib/lib.odin

@@ -34,6 +34,7 @@ Example:
 		LIBRARY_PATH :: "my_library.dll"
 		library, ok := dynlib.load_library(LIBRARY_PATH)
 		if ! ok {
+			fmt.eprintln(dynlib.last_error())
 			return
 		}
 		fmt.println("The library %q was successfully loaded", LIBRARY_PATH)
@@ -58,10 +59,12 @@ Example:
 		LIBRARY_PATH :: "my_library.dll"
 		library, ok := dynlib.load_library(LIBRARY_PATH)
 		if ! ok {
+			fmt.eprintln(dynlib.last_error())
 			return
 		}
 		did_unload := dynlib.unload_library(library)
 		if ! did_unload {
+			fmt.eprintln(dynlib.last_error())
 			return
 		}
 		fmt.println("The library %q was successfully unloaded", LIBRARY_PATH)
@@ -89,11 +92,16 @@ Example:
 		LIBRARY_PATH :: "my_library.dll"
 		library, ok := dynlib.load_library(LIBRARY_PATH)
 		if ! ok {
+			fmt.eprintln(dynlib.last_error())
 			return
 		}
 
 		a, found_a := dynlib.symbol_address(library, "a")
-		if found_a do fmt.printf("The symbol %q was found at the address %v", "a", a)
+		if found_a {
+			fmt.printf("The symbol %q was found at the address %v", "a", a)
+		} else {
+			fmt.eprintln(dynlib.last_error())
+		}
 	}
 */
 symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) #optional_ok {
@@ -166,4 +174,11 @@ initialize_symbols :: proc(symbol_table: ^$T, library_name: string, symbol_prefi
 		}
 	}
 	return count, count > 0
-}
+}
+
+/*
+Returns an error message for the last failed procedure call.
+*/
+last_error :: proc() -> string {
+	return _last_error()
+}

+ 4 - 0
core/dynlib/lib_js.odin

@@ -13,3 +13,7 @@ _unload_library :: proc(library: Library) -> bool {
 _symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
 	return nil, false
 }
+
+_last_error :: proc() -> string {
+	return ""
+}

+ 5 - 0
core/dynlib/lib_unix.odin

@@ -22,3 +22,8 @@ _symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found
 	found = ptr != nil
 	return
 }
+
+_last_error :: proc() -> string {
+	err := os.dlerror()
+	return "unknown" if err == "" else err
+}

+ 7 - 0
core/dynlib/lib_windows.odin

@@ -5,6 +5,7 @@ package dynlib
 import win32 "core:sys/windows"
 import "core:strings"
 import "core:runtime"
+import "core:reflect"
 
 _load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
 	// NOTE(bill): 'global_symbols' is here only for consistency with POSIX which has RTLD_GLOBAL
@@ -27,3 +28,9 @@ _symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found
 	found = ptr != nil
 	return
 }
+
+_last_error :: proc() -> string {
+	err := win32.System_Error(win32.GetLastError())
+	err_msg := reflect.enum_string(err)
+	return "unknown" if err_msg == "" else err_msg
+}