mirror of
https://github.com/ziglang/zig.git
synced 2025-12-25 07:33:08 +00:00
Merge pull request #1594 from emekoi/master
added dynamic library loading for windows
This commit is contained in:
commit
a42a213e35
@ -1,10 +1,23 @@
|
||||
const builtin = @import("builtin");
|
||||
const Os = builtin.Os;
|
||||
|
||||
const std = @import("index.zig");
|
||||
const mem = std.mem;
|
||||
const elf = std.elf;
|
||||
const cstr = std.cstr;
|
||||
const linux = std.os.linux;
|
||||
const os = std.os;
|
||||
const assert = std.debug.assert;
|
||||
const elf = std.elf;
|
||||
const linux = os.linux;
|
||||
const windows = os.windows;
|
||||
const win_util = @import("os/windows/util.zig");
|
||||
|
||||
pub const DynLib = struct {
|
||||
pub const DynLib = switch (builtin.os) {
|
||||
Os.linux => LinuxDynLib,
|
||||
Os.windows => WindowsDynLib,
|
||||
else => void,
|
||||
};
|
||||
|
||||
pub const LinuxDynLib = struct {
|
||||
allocator: *mem.Allocator,
|
||||
elf_lib: ElfLib,
|
||||
fd: i32,
|
||||
@ -107,7 +120,7 @@ pub const ElfLib = struct {
|
||||
}
|
||||
}
|
||||
|
||||
return ElfLib{
|
||||
return ElfLib {
|
||||
.base = base,
|
||||
.strings = maybe_strings orelse return error.ElfStringSectionNotFound,
|
||||
.syms = maybe_syms orelse return error.ElfSymSectionNotFound,
|
||||
@ -154,3 +167,48 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [
|
||||
const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux);
|
||||
return mem.eql(u8, vername, cstr.toSliceConst(strings + aux.vda_name));
|
||||
}
|
||||
|
||||
pub const WindowsDynLib = struct {
|
||||
allocator: *mem.Allocator,
|
||||
dll: windows.HMODULE,
|
||||
|
||||
pub fn open(allocator: *mem.Allocator, path: []const u8) !WindowsDynLib {
|
||||
const wpath = try win_util.sliceToPrefixedFileW(path);
|
||||
|
||||
return WindowsDynLib {
|
||||
.allocator = allocator,
|
||||
.dll = windows.LoadLibraryW(&wpath) orelse {
|
||||
const err = windows.GetLastError();
|
||||
switch (err) {
|
||||
windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound,
|
||||
windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound,
|
||||
windows.ERROR.MOD_NOT_FOUND => return error.FileNotFound,
|
||||
else => return os.unexpectedErrorWindows(err),
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn close(self: *WindowsDynLib) void {
|
||||
assert(windows.FreeLibrary(self.dll) != 0);
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn lookup(self: *WindowsDynLib, name: []const u8) ?usize {
|
||||
return @ptrToInt(windows.GetProcAddress(self.dll, name.ptr));
|
||||
}
|
||||
};
|
||||
|
||||
test "dynamic_library" {
|
||||
const libname = switch (builtin.os) {
|
||||
Os.linux => "invalid_so.so",
|
||||
Os.windows => "invalid_dll.dll",
|
||||
else => return;,
|
||||
};
|
||||
|
||||
const dynlib = DynLib.open(std.debug.global_allocator, libname) catch |err| {
|
||||
assert(err == error.FileNotFound);
|
||||
return;
|
||||
};
|
||||
@panic("Expected error from function");
|
||||
}
|
||||
|
||||
@ -58,8 +58,6 @@ pub const windowsWrite = windows_util.windowsWrite;
|
||||
pub const windowsIsCygwinPty = windows_util.windowsIsCygwinPty;
|
||||
pub const windowsOpen = windows_util.windowsOpen;
|
||||
pub const windowsOpenW = windows_util.windowsOpenW;
|
||||
pub const windowsLoadDll = windows_util.windowsLoadDll;
|
||||
pub const windowsUnloadDll = windows_util.windowsUnloadDll;
|
||||
pub const createWindowsEnvBlock = windows_util.createWindowsEnvBlock;
|
||||
|
||||
pub const WindowsCreateIoCompletionPortError = windows_util.WindowsCreateIoCompletionPortError;
|
||||
|
||||
@ -24,6 +24,7 @@ pub const HANDLE = *c_void;
|
||||
pub const HCRYPTPROV = ULONG_PTR;
|
||||
pub const HINSTANCE = *@OpaqueType();
|
||||
pub const HMODULE = *@OpaqueType();
|
||||
pub const FARPROC = *@OpaqueType();
|
||||
pub const INT = c_int;
|
||||
pub const LPBYTE = *BYTE;
|
||||
pub const LPCH = *CHAR;
|
||||
|
||||
@ -178,6 +178,8 @@ pub extern "kernel32" stdcallcc fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const
|
||||
|
||||
pub extern "kernel32" stdcallcc fn LoadLibraryW(lpLibFileName: [*]const u16) ?HMODULE;
|
||||
|
||||
pub extern "kernel32" stdcallcc fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) ?FARPROC;
|
||||
|
||||
pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL;
|
||||
|
||||
pub const FILE_NOTIFY_INFORMATION = extern struct {
|
||||
|
||||
@ -188,37 +188,6 @@ pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap)
|
||||
return allocator.shrink(u16, result, i);
|
||||
}
|
||||
|
||||
pub fn windowsLoadDllW(dll_path_w: [*]const u16) !windows.HMODULE {
|
||||
return windows.LoadLibraryW(dll_path_w) orelse {
|
||||
const err = windows.GetLastError();
|
||||
switch (err) {
|
||||
windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound,
|
||||
windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound,
|
||||
windows.ERROR.MOD_NOT_FOUND => return error.FileNotFound,
|
||||
else => return os.unexpectedErrorWindows(err),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn windowsLoadDll(dll_path: []const u8) !windows.HMODULE {
|
||||
const dll_path_w = try sliceToPrefixedFileW(dll_path);
|
||||
return windowsLoadDllW(&dll_path_w);
|
||||
}
|
||||
|
||||
pub fn windowsUnloadDll(hModule: windows.HMODULE) void {
|
||||
assert(windows.FreeLibrary(hModule) != 0);
|
||||
}
|
||||
|
||||
test "InvalidDll" {
|
||||
if (builtin.os != builtin.Os.windows) return error.SkipZigTest;
|
||||
|
||||
const handle = os.windowsLoadDll("asdf.dll") catch |err| {
|
||||
assert(err == error.FileNotFound);
|
||||
return;
|
||||
};
|
||||
@panic("Expected error from function");
|
||||
}
|
||||
|
||||
pub fn windowsFindFirstFile(
|
||||
dir_path: []const u8,
|
||||
find_file_data: *windows.WIN32_FIND_DATAW,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user