Skip to content

Commit bc76d54

Browse files
committed
Port SKSupport to Windows
1 parent 6d6f899 commit bc76d54

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

Sources/SKSupport/dlopen.swift

Lines changed: 42 additions & 8 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.FreeLibrary("Failed to FreeLibrary: \(GetLastError())")
36+
}
37+
#else
38+
guard dlclose(handle) == 0 else {
39+
throw DLError.dlclose(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

@@ -60,32 +73,53 @@ public struct DLOpenFlags: RawRepresentable, OptionSet {
6073
}
6174
}
6275

76+
#if os(Windows)
77+
public enum DLError: Swift.Error {
78+
case LoadLibrary(String)
79+
case FreeLibrary(String)
80+
}
81+
#else
6382
public enum DLError: Swift.Error {
6483
case dlopen(String)
6584
case dlclose(String)
6685
}
86+
#endif
6787

6888
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-
}
89+
#if os(Windows)
90+
guard let handle = path?.withCString(encodedAs: UTF16.self, LoadLibraryW) else {
91+
throw DLError.LoadLibrary("LoadLibraryW failed: \(GetLastError())")
92+
}
93+
#else
94+
guard let handle = SPMLibc.dlopen(path, mode.rawValue) else {
95+
throw DLError.dlopen(dlerror() ?? "unknown error")
96+
}
97+
#endif
7298
return DLHandle(rawValue: handle)
7399
}
74100

75101
public func dlsym<T>(_ handle: DLHandle, symbol: String) -> T? {
102+
#if os(Windows)
103+
guard let ptr = GetProcAddress(handle.rawValue!, symbol) else {
104+
return nil
105+
}
106+
#else
76107
guard let ptr = dlsym(handle.rawValue!, symbol) else {
77108
return nil
78109
}
110+
#endif
79111
return unsafeBitCast(ptr, to: T.self)
80112
}
81113

82114
public func dlclose(_ handle: DLHandle) throws {
83115
try handle.close()
84116
}
85117

118+
#if !os(Windows)
86119
public func dlerror() -> String? {
87120
if let err: UnsafeMutablePointer<Int8> = dlerror() {
88121
return String(cString: err)
89122
}
90123
return nil
91124
}
125+
#endif

0 commit comments

Comments
 (0)