13
13
import SPMLibc
14
14
15
15
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
17
22
18
- init ( rawValue: UnsafeMutableRawPointer ) {
23
+ init ( rawValue: Handle ) {
19
24
self . rawValue = rawValue
20
25
}
21
26
@@ -25,9 +30,15 @@ public final class DLHandle {
25
30
26
31
public func close( ) throws {
27
32
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
31
42
}
32
43
rawValue = nil
33
44
}
@@ -39,6 +50,7 @@ public final class DLHandle {
39
50
40
51
public struct DLOpenFlags : RawRepresentable , OptionSet {
41
52
53
+ #if !os(Windows)
42
54
public static let lazy : DLOpenFlags = DLOpenFlags ( rawValue: RTLD_LAZY)
43
55
public static let now : DLOpenFlags = DLOpenFlags ( rawValue: RTLD_NOW)
44
56
public static let local : DLOpenFlags = DLOpenFlags ( rawValue: RTLD_LOCAL)
@@ -52,6 +64,7 @@ public struct DLOpenFlags: RawRepresentable, OptionSet {
52
64
public static let first : DLOpenFlags = DLOpenFlags ( rawValue: 0 )
53
65
public static let deepBind : DLOpenFlags = DLOpenFlags ( rawValue: RTLD_DEEPBIND)
54
66
#endif
67
+ #endif
55
68
56
69
public var rawValue : Int32
57
70
@@ -61,31 +74,45 @@ public struct DLOpenFlags: RawRepresentable, OptionSet {
61
74
}
62
75
63
76
public enum DLError : Swift . Error {
64
- case dlopen ( String )
65
- case dlclose ( String )
77
+ case `open` ( String )
78
+ case close ( String )
66
79
}
67
80
68
81
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
72
91
return DLHandle ( rawValue: handle)
73
92
}
74
93
75
94
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
76
100
guard let ptr = dlsym ( handle. rawValue!, symbol) else {
77
101
return nil
78
102
}
103
+ #endif
79
104
return unsafeBitCast ( ptr, to: T . self)
80
105
}
81
106
82
107
public func dlclose( _ handle: DLHandle ) throws {
83
108
try handle. close ( )
84
109
}
85
110
111
+ #if !os(Windows)
86
112
public func dlerror( ) -> String ? {
87
113
if let err: UnsafeMutablePointer < Int8 > = dlerror ( ) {
88
114
return String ( cString: err)
89
115
}
90
116
return nil
91
117
}
118
+ #endif
0 commit comments