mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-18 08:58:23 +00:00
Add hot reload support to dynlib.initialize_symbols
This commit is contained in:
@@ -26,7 +26,16 @@ main :: proc() {
|
||||
// The library's Handle (to unload) will be stored in `sym._my_lib_handle`. This way you can load multiple DLLs in one struct.
|
||||
count, ok := dynlib.initialize_symbols(&sym, "lib.dll", "foo_", "_my_lib_handle")
|
||||
defer dynlib.unload_library(sym._my_lib_handle)
|
||||
fmt.printf("ok: %v. %v symbols loaded from lib.dll (%p).\n", ok, count, sym._my_lib_handle)
|
||||
fmt.printf("(Initial DLL Load) ok: %v. %v symbols loaded from lib.dll (%p).\n", ok, count, sym._my_lib_handle)
|
||||
|
||||
if count > 0 {
|
||||
fmt.println("42 + 42 =", sym.add(42, 42))
|
||||
fmt.println("84 - 13 =", sym.sub(84, 13))
|
||||
fmt.println("hellope =", sym.hellope^)
|
||||
}
|
||||
|
||||
count, ok = dynlib.initialize_symbols(&sym, "lib.dll", "foo_", "_my_lib_handle")
|
||||
fmt.printf("(DLL Reload) ok: %v. %v symbols loaded from lib.dll (%p).\n", ok, count, sym._my_lib_handle)
|
||||
|
||||
if count > 0 {
|
||||
fmt.println("42 + 42 =", sym.add(42, 42))
|
||||
|
||||
@@ -115,17 +115,19 @@ Optionally also takes the struct member to assign the library handle to, `__hand
|
||||
|
||||
This allows using one struct to hold library handles and symbol pointers for more than 1 dynamic library.
|
||||
|
||||
Loading the same library twice unloads the previous incarnation, allowing for straightforward hot reload support.
|
||||
|
||||
Returns:
|
||||
* `-1, false` if the library could not be loaded.
|
||||
* The number of symbols assigned on success. `ok` = true if `count` > 0
|
||||
|
||||
See doc.odin for an example.
|
||||
*/
|
||||
initialize_symbols :: proc(symbol_table: ^$T, library_name: string, symbol_prefix := "", handle_field_name := "__handle") -> (count: int, ok: bool) where intrinsics.type_is_struct(T) {
|
||||
initialize_symbols :: proc(symbol_table: ^$T, library_path: string, symbol_prefix := "", handle_field_name := "__handle") -> (count: int, ok: bool) where intrinsics.type_is_struct(T) {
|
||||
assert(symbol_table != nil)
|
||||
handle: Library
|
||||
|
||||
if handle, ok = load_library(library_name); !ok {
|
||||
if handle, ok = load_library(library_path); !ok {
|
||||
return -1, false
|
||||
}
|
||||
|
||||
@@ -143,6 +145,12 @@ initialize_symbols :: proc(symbol_table: ^$T, library_name: string, symbol_prefi
|
||||
|
||||
// If we've come across the struct member for the handle, store it and continue scanning for other symbols.
|
||||
if field_name == handle_field_name {
|
||||
// We appear to be hot reloading. Unload previous incarnation of the library.
|
||||
if old_handle := (^Library)(field_ptr)^; old_handle != nil {
|
||||
if ok = unload_library(old_handle); !ok {
|
||||
return count, ok
|
||||
}
|
||||
}
|
||||
(^Library)(field_ptr)^ = handle
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user