浏览代码

Merge branch 'master' into core_net_update

Colin Davidson 2 年之前
父节点
当前提交
090723179b
共有 4 个文件被更改,包括 141 次插入34 次删除
  1. 7 0
      core/dynlib/doc.odin
  2. 81 2
      core/dynlib/lib.odin
  3. 3 0
      core/sys/windows/kernel32.odin
  4. 50 32
      core/sys/windows/types.odin

+ 7 - 0
core/dynlib/doc.odin

@@ -0,0 +1,7 @@
+/*
+Package core:dynlib implements loading of shared libraries/DLLs and their symbols.
+
+The behaviour of dynamically loaded libraries is specific to the target platform of the program.
+For in depth detail on the underlying behaviour please refer to your target platform's documentation.
+*/
+package dynlib

+ 81 - 2
core/dynlib/lib.odin

@@ -1,15 +1,94 @@
 package dynlib
 
+/*
+A handle to a dynamically loaded library.
+*/
 Library :: distinct rawptr
 
-load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
+/*
+Loads a dynamic library from the filesystem. The paramater `global_symbols` makes the symbols in the loaded
+library available to resolve references in subsequently loaded libraries.
+
+The paramater `global_symbols` is only used for the platforms `linux`, `darwin`, `freebsd` and `openbsd`.
+On `windows` this paramater is ignored.
+
+The underlying behaviour is platform specific.  
+On `linux`, `darwin`, `freebsd` and `openbsd` refer to `dlopen`.  
+On `windows` refer to `LoadLibraryW`.
+
+**Implicit Allocators**  
+`context.temp_allocator`
+
+Example:
+	import "core:dynlib"
+	import "core:fmt"
+
+	load_my_library :: proc() {
+		LIBRARY_PATH :: "my_library.dll"
+		library, ok := dynlib.load_library(LIBRARY_PATH)
+		if ! ok {
+			return
+		}
+		fmt.println("The library %q was successfully loaded", LIBRARY_PATH)
+	}
+*/
+load_library :: proc(path: string, global_symbols := false) -> (library: Library, did_load: bool) {
 	return _load_library(path, global_symbols)
 }
 
-unload_library :: proc(library: Library) -> bool {
+/*
+Unloads a dynamic library.
+
+The underlying behaviour is platform specific.  
+On `linux`, `darwin`, `freebsd` and `openbsd` refer to `dlclose`.  
+On `windows` refer to `FreeLibrary`.
+
+Example:
+	import "core:dynlib"
+	import "core:fmt"
+
+	load_then_unload_my_library :: proc() {
+		LIBRARY_PATH :: "my_library.dll"
+		library, ok := dynlib.load_library(LIBRARY_PATH)
+		if ! ok {
+			return
+		}
+		did_unload := dynlib.unload_library(library)
+		if ! did_unload {
+			return
+		}
+		fmt.println("The library %q was successfully unloaded", LIBRARY_PATH)
+	}
+*/
+unload_library :: proc(library: Library) -> (did_unload: bool) {
 	return _unload_library(library)
 }
 
+/*
+Loads the address of a procedure/variable from a dynamic library.
+
+The underlying behaviour is platform specific.  
+On `linux`, `darwin`, `freebsd` and `openbsd` refer to `dlsym`.  
+On `windows` refer to `GetProcAddress`.
+
+**Implicit Allocators**  
+`context.temp_allocator`
+
+Example:
+	import "core:dynlib"
+	import "core:fmt"
+
+	find_a_in_my_library :: proc() {
+		LIBRARY_PATH :: "my_library.dll"
+		library, ok := dynlib.load_library(LIBRARY_PATH)
+		if ! ok {
+			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)
+	}
+*/
 symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) #optional_ok {
 	return _symbol_address(library, symbol)
 }

+ 3 - 0
core/sys/windows/kernel32.odin

@@ -370,6 +370,9 @@ foreign kernel32 {
 	GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL ---
 	FreeConsole :: proc() -> BOOL ---
 	GetConsoleWindow :: proc() -> HWND ---
+	GetConsoleScreenBufferInfo :: proc(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: PCONSOLE_SCREEN_BUFFER_INFO) -> BOOL ---
+	SetConsoleScreenBufferSize :: proc(hConsoleOutput: HANDLE, dwSize: COORD) -> BOOL ---
+	SetConsoleWindowInfo :: proc(hConsoleOutput: HANDLE, bAbsolute : BOOL, lpConsoleWindow: ^SMALL_RECT) -> BOOL ---
 
 	GetDiskFreeSpaceExW :: proc(
 		lpDirectoryName: LPCWSTR,

+ 50 - 32
core/sys/windows/types.odin

@@ -3767,6 +3767,24 @@ COORD :: struct {
 	Y: SHORT,
 }
 
+SMALL_RECT :: struct {
+	Left: SHORT,
+	Top: SHORT,
+	Right: SHORT,
+	Bottom: SHORT,
+}
+
+CONSOLE_SCREEN_BUFFER_INFO :: struct {
+	dwSize: COORD,
+	dwCursorPosition: COORD,
+	wAttributes: WORD,
+	srWindow: SMALL_RECT,
+	dwMaximumWindowSize: COORD,
+}
+
+
+PCONSOLE_SCREEN_BUFFER_INFO :: ^CONSOLE_SCREEN_BUFFER_INFO
+
 //
 // Networking
 //
@@ -3909,39 +3927,39 @@ ipv6_mreq :: struct {
 }
 
 SOCKADDR_STORAGE_LH :: struct {
-	ss_family: ADDRESS_FAMILY,
-	__ss_pad1: [6]CHAR,
+	ss_family:  ADDRESS_FAMILY,
+	__ss_pad1:  [6]CHAR,
 	__ss_align: i64,
-	__ss_pad2: [112]CHAR,
+	__ss_pad2:  [112]CHAR,
 }
 
 ADDRINFOA :: struct {
-	ai_flags: c_int,
-	ai_family: c_int,
-	ai_socktype: c_int,
-	ai_protocol: c_int,
-	ai_addrlen: size_t,
+	ai_flags:     c_int,
+	ai_family:    c_int,
+	ai_socktype:  c_int,
+	ai_protocol:  c_int,
+	ai_addrlen:   size_t,
 	ai_canonname: ^c_char,
-	ai_addr: ^SOCKADDR,
-	ai_next: ^ADDRINFOA,
+	ai_addr:      ^SOCKADDR,
+	ai_next:      ^ADDRINFOA,
 }
 
 sockaddr :: struct {
 	sa_family: USHORT,
-	sa_data: [14]byte,
+	sa_data:   [14]byte,
 }
 
 sockaddr_in :: struct {
 	sin_family: ADDRESS_FAMILY,
-	sin_port: u16be,
-	sin_addr: in_addr,
-	sin_zero: [8]CHAR,
+	sin_port:   u16be,
+	sin_addr:   in_addr,
+	sin_zero:   [8]CHAR,
 }
 sockaddr_in6 :: struct {
-	sin6_family: ADDRESS_FAMILY,
-	sin6_port: u16be,
+	sin6_family:   ADDRESS_FAMILY,
+	sin6_port:     u16be,
 	sin6_flowinfo: c_ulong,
-	sin6_addr: in6_addr,
+	sin6_addr:     in6_addr,
 	sin6_scope_id: c_ulong,
 }
 
@@ -3968,36 +3986,36 @@ DNS_RECORD :: struct {
     _: DWORD,
     Data: struct #raw_union {
         CNAME: DNS_PTR_DATAA,
-        A: u32be, // Ipv4 Address
-        AAAA: u128be, // Ipv6 Address
-        TXT: DNS_TXT_DATAA,
-        NS: DNS_PTR_DATAA,
-        MX: DNS_MX_DATAA,
-        SRV: DNS_SRV_DATAA,
+        A:     u32be,  // Ipv4 Address
+        AAAA:  u128be, // Ipv6 Address
+        TXT:   DNS_TXT_DATAA,
+        NS:    DNS_PTR_DATAA,
+        MX:    DNS_MX_DATAA,
+        SRV:   DNS_SRV_DATAA,
     },
 }
 
 DNS_TXT_DATAA :: struct {
     dwStringCount: DWORD,
-    pStringArray: cstring,
+    pStringArray:  cstring,
 }
 
 DNS_PTR_DATAA :: cstring
 
 DNS_MX_DATAA :: struct {
     pNameExchange: cstring, // the hostname
-    wPreference: WORD, // lower values preferred
-    _: WORD, // padding.
+    wPreference: WORD,      // lower values preferred
+    _: WORD,                // padding.
 }
 DNS_SRV_DATAA :: struct {
 	pNameTarget: cstring,
-	wPriority: u16,
-	wWeight: u16,
-	wPort: u16,
-	_: WORD, // padding
+	wPriority:   u16,
+	wWeight:     u16,
+	wPort:       u16,
+	_:           WORD, // padding
 }
 
 SOCKADDR :: struct {
 	sa_family: ADDRESS_FAMILY,
-	sa_data: [14]CHAR,
-}
+	sa_data:   [14]CHAR,
+}