| author | |
| committer | |
| log | a42a213e35842e18750dd8cfdfc0d024e23da50b |
| tree | e766cb115890713ec2d5522e3f5ba59032dd881a |
| parent | e6446dfc86e42ccea93760d99cf4b421265cfb0e |
| parent | 623f5085f152b3a2fedf3b4e4451910f1edb6739 |
| signature | Signed by PGP key 4AEE18F83AFDEB23 |
added dynamic library loading for windows5 files changed, 65 insertions(+), 37 deletions(-)
std/dynamic_library.zig+62-4| ... | ... | @@ -1,10 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const Os = builtin.Os; | |
| 3 | ||
| 1 | 4 | const std = @import("index.zig"); |
| 2 | 5 | const mem = std.mem; |
| 3 | const elf = std.elf; | |
| 4 | 6 | const cstr = std.cstr; |
| 5 | const linux = std.os.linux; | |
| 7 | const os = std.os; | |
| 8 | const assert = std.debug.assert; | |
| 9 | const elf = std.elf; | |
| 10 | const linux = os.linux; | |
| 11 | const windows = os.windows; | |
| 12 | const win_util = @import("os/windows/util.zig"); | |
| 13 | ||
| 14 | pub const DynLib = switch (builtin.os) { | |
| 15 | Os.linux => LinuxDynLib, | |
| 16 | Os.windows => WindowsDynLib, | |
| 17 | else => void, | |
| 18 | }; | |
| 6 | 19 | |
| 7 | pub const DynLib = struct { | |
| 20 | pub const LinuxDynLib = struct { | |
| 8 | 21 | allocator: *mem.Allocator, |
| 9 | 22 | elf_lib: ElfLib, |
| 10 | 23 | fd: i32, |
| ... | ... | @@ -107,7 +120,7 @@ pub const ElfLib = struct { |
| 107 | 120 | } |
| 108 | 121 | } |
| 109 | 122 | |
| 110 | return ElfLib{ | |
| 123 | return ElfLib { | |
| 111 | 124 | .base = base, |
| 112 | 125 | .strings = maybe_strings orelse return error.ElfStringSectionNotFound, |
| 113 | 126 | .syms = maybe_syms orelse return error.ElfSymSectionNotFound, |
| ... | ... | @@ -154,3 +167,48 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [ |
| 154 | 167 | const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux); |
| 155 | 168 | return mem.eql(u8, vername, cstr.toSliceConst(strings + aux.vda_name)); |
| 156 | 169 | } |
| 170 | ||
| 171 | pub const WindowsDynLib = struct { | |
| 172 | allocator: *mem.Allocator, | |
| 173 | dll: windows.HMODULE, | |
| 174 | ||
| 175 | pub fn open(allocator: *mem.Allocator, path: []const u8) !WindowsDynLib { | |
| 176 | const wpath = try win_util.sliceToPrefixedFileW(path); | |
| 177 | ||
| 178 | return WindowsDynLib { | |
| 179 | .allocator = allocator, | |
| 180 | .dll = windows.LoadLibraryW(&wpath) orelse { | |
| 181 | const err = windows.GetLastError(); | |
| 182 | switch (err) { | |
| 183 | windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound, | |
| 184 | windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound, | |
| 185 | windows.ERROR.MOD_NOT_FOUND => return error.FileNotFound, | |
| 186 | else => return os.unexpectedErrorWindows(err), | |
| 187 | } | |
| 188 | }, | |
| 189 | }; | |
| 190 | } | |
| 191 | ||
| 192 | pub fn close(self: *WindowsDynLib) void { | |
| 193 | assert(windows.FreeLibrary(self.dll) != 0); | |
| 194 | self.* = undefined; | |
| 195 | } | |
| 196 | ||
| 197 | pub fn lookup(self: *WindowsDynLib, name: []const u8) ?usize { | |
| 198 | return @ptrToInt(windows.GetProcAddress(self.dll, name.ptr)); | |
| 199 | } | |
| 200 | }; | |
| 201 | ||
| 202 | test "dynamic_library" { | |
| 203 | const libname = switch (builtin.os) { | |
| 204 | Os.linux => "invalid_so.so", | |
| 205 | Os.windows => "invalid_dll.dll", | |
| 206 | else => return;, | |
| 207 | }; | |
| 208 | ||
| 209 | const dynlib = DynLib.open(std.debug.global_allocator, libname) catch |err| { | |
| 210 | assert(err == error.FileNotFound); | |
| 211 | return; | |
| 212 | }; | |
| 213 | @panic("Expected error from function"); | |
| 214 | } |
std/os/index.zig-2| ... | ... | @@ -58,8 +58,6 @@ pub const windowsWrite = windows_util.windowsWrite; |
| 58 | 58 | pub const windowsIsCygwinPty = windows_util.windowsIsCygwinPty; |
| 59 | 59 | pub const windowsOpen = windows_util.windowsOpen; |
| 60 | 60 | pub const windowsOpenW = windows_util.windowsOpenW; |
| 61 | pub const windowsLoadDll = windows_util.windowsLoadDll; | |
| 62 | pub const windowsUnloadDll = windows_util.windowsUnloadDll; | |
| 63 | 61 | pub const createWindowsEnvBlock = windows_util.createWindowsEnvBlock; |
| 64 | 62 | |
| 65 | 63 | pub const WindowsCreateIoCompletionPortError = windows_util.WindowsCreateIoCompletionPortError; |
std/os/windows/index.zig+1| ... | ... | @@ -24,6 +24,7 @@ pub const HANDLE = *c_void; |
| 24 | 24 | pub const HCRYPTPROV = ULONG_PTR; |
| 25 | 25 | pub const HINSTANCE = *@OpaqueType(); |
| 26 | 26 | pub const HMODULE = *@OpaqueType(); |
| 27 | pub const FARPROC = *@OpaqueType(); | |
| 27 | 28 | pub const INT = c_int; |
| 28 | 29 | pub const LPBYTE = *BYTE; |
| 29 | 30 | pub const LPCH = *CHAR; |
std/os/windows/kernel32.zig+2| ... | ... | @@ -178,6 +178,8 @@ pub extern "kernel32" stdcallcc fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const |
| 178 | 178 | |
| 179 | 179 | pub extern "kernel32" stdcallcc fn LoadLibraryW(lpLibFileName: [*]const u16) ?HMODULE; |
| 180 | 180 | |
| 181 | pub extern "kernel32" stdcallcc fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) ?FARPROC; | |
| 182 | ||
| 181 | 183 | pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL; |
| 182 | 184 | |
| 183 | 185 | pub const FILE_NOTIFY_INFORMATION = extern struct { |
std/os/windows/util.zig-31| ... | ... | @@ -188,37 +188,6 @@ pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap) |
| 188 | 188 | return allocator.shrink(u16, result, i); |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | pub fn windowsLoadDllW(dll_path_w: [*]const u16) !windows.HMODULE { | |
| 192 | return windows.LoadLibraryW(dll_path_w) orelse { | |
| 193 | const err = windows.GetLastError(); | |
| 194 | switch (err) { | |
| 195 | windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound, | |
| 196 | windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound, | |
| 197 | windows.ERROR.MOD_NOT_FOUND => return error.FileNotFound, | |
| 198 | else => return os.unexpectedErrorWindows(err), | |
| 199 | } | |
| 200 | }; | |
| 201 | } | |
| 202 | ||
| 203 | pub fn windowsLoadDll(dll_path: []const u8) !windows.HMODULE { | |
| 204 | const dll_path_w = try sliceToPrefixedFileW(dll_path); | |
| 205 | return windowsLoadDllW(&dll_path_w); | |
| 206 | } | |
| 207 | ||
| 208 | pub fn windowsUnloadDll(hModule: windows.HMODULE) void { | |
| 209 | assert(windows.FreeLibrary(hModule) != 0); | |
| 210 | } | |
| 211 | ||
| 212 | test "InvalidDll" { | |
| 213 | if (builtin.os != builtin.Os.windows) return error.SkipZigTest; | |
| 214 | ||
| 215 | const handle = os.windowsLoadDll("asdf.dll") catch |err| { | |
| 216 | assert(err == error.FileNotFound); | |
| 217 | return; | |
| 218 | }; | |
| 219 | @panic("Expected error from function"); | |
| 220 | } | |
| 221 | ||
| 222 | 191 | pub fn windowsFindFirstFile( |
| 223 | 192 | dir_path: []const u8, |
| 224 | 193 | find_file_data: *windows.WIN32_FIND_DATAW, |