Skip to content

Commit 4d30353

Browse files
authored
Merge pull request #99 from gmittert/SKSupportWin
Add Windows Support to SKSupport
2 parents 31fea30 + 942ed5d commit 4d30353

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

Sources/SKSupport/dlopen.swift

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,14 @@
1313
import SPMLibc
1414

1515
public final class DLHandle {
16-
var rawValue: UnsafeMutableRawPointer? = nil
16+
#if os(Windows)
17+
typealias Handle = HMODULE
18+
#else
19+
typealias Handle = UnsafeMutableRawPointer
20+
#endif
21+
var rawValue: Handle? = nil
1722

18-
init(rawValue: UnsafeMutableRawPointer) {
23+
init(rawValue: Handle) {
1924
self.rawValue = rawValue
2025
}
2126

@@ -25,9 +30,15 @@ public final class DLHandle {
2530

2631
public func close() throws {
2732
if let handle = rawValue {
28-
guard dlclose(handle) == 0 else {
29-
throw DLError.dlclose(dlerror() ?? "unknown error")
30-
}
33+
#if os(Windows)
34+
guard FreeLibrary(handle) != 0 else {
35+
throw DLError.close("Failed to FreeLibrary: \(GetLastError())")
36+
}
37+
#else
38+
guard dlclose(handle) == 0 else {
39+
throw DLError.close(dlerror() ?? "unknown error")
40+
}
41+
#endif
3142
}
3243
rawValue = nil
3344
}
@@ -39,6 +50,7 @@ public final class DLHandle {
3950

4051
public struct DLOpenFlags: RawRepresentable, OptionSet {
4152

53+
#if !os(Windows)
4254
public static let lazy: DLOpenFlags = DLOpenFlags(rawValue: RTLD_LAZY)
4355
public static let now: DLOpenFlags = DLOpenFlags(rawValue: RTLD_NOW)
4456
public static let local: DLOpenFlags = DLOpenFlags(rawValue: RTLD_LOCAL)
@@ -52,6 +64,7 @@ public struct DLOpenFlags: RawRepresentable, OptionSet {
5264
public static let first: DLOpenFlags = DLOpenFlags(rawValue: 0)
5365
public static let deepBind: DLOpenFlags = DLOpenFlags(rawValue: RTLD_DEEPBIND)
5466
#endif
67+
#endif
5568

5669
public var rawValue: Int32
5770

@@ -61,31 +74,45 @@ public struct DLOpenFlags: RawRepresentable, OptionSet {
6174
}
6275

6376
public enum DLError: Swift.Error {
64-
case dlopen(String)
65-
case dlclose(String)
77+
case `open`(String)
78+
case close(String)
6679
}
6780

6881
public func dlopen(_ path: String?, mode: DLOpenFlags) throws -> DLHandle {
69-
guard let handle = SPMLibc.dlopen(path, mode.rawValue) else {
70-
throw DLError.dlopen(dlerror() ?? "unknown error")
71-
}
82+
#if os(Windows)
83+
guard let handle = path?.withCString(encodedAs: UTF16.self, LoadLibraryW) else {
84+
throw DLError.open("LoadLibraryW failed: \(GetLastError())")
85+
}
86+
#else
87+
guard let handle = SPMLibc.dlopen(path, mode.rawValue) else {
88+
throw DLError.open(dlerror() ?? "unknown error")
89+
}
90+
#endif
7291
return DLHandle(rawValue: handle)
7392
}
7493

7594
public func dlsym<T>(_ handle: DLHandle, symbol: String) -> T? {
95+
#if os(Windows)
96+
guard let ptr = GetProcAddress(handle.rawValue!, symbol) else {
97+
return nil
98+
}
99+
#else
76100
guard let ptr = dlsym(handle.rawValue!, symbol) else {
77101
return nil
78102
}
103+
#endif
79104
return unsafeBitCast(ptr, to: T.self)
80105
}
81106

82107
public func dlclose(_ handle: DLHandle) throws {
83108
try handle.close()
84109
}
85110

111+
#if !os(Windows)
86112
public func dlerror() -> String? {
87113
if let err: UnsafeMutablePointer<Int8> = dlerror() {
88114
return String(cString: err)
89115
}
90116
return nil
91117
}
118+
#endif

0 commit comments

Comments
 (0)