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 . FreeLibrary ( " Failed to FreeLibrary: \( GetLastError ( ) ) " )
36
+ }
37
+ #else
38
+ guard dlclose ( handle) == 0 else {
39
+ throw DLError . dlclose ( 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
@@ -60,32 +73,53 @@ public struct DLOpenFlags: RawRepresentable, OptionSet {
60
73
}
61
74
}
62
75
76
+ #if os(Windows)
77
+ public enum DLError : Swift . Error {
78
+ case LoadLibrary( String )
79
+ case FreeLibrary( String )
80
+ }
81
+ #else
63
82
public enum DLError : Swift . Error {
64
83
case dlopen( String )
65
84
case dlclose( String )
66
85
}
86
+ #endif
67
87
68
88
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
72
98
return DLHandle ( rawValue: handle)
73
99
}
74
100
75
101
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
76
107
guard let ptr = dlsym ( handle. rawValue!, symbol) else {
77
108
return nil
78
109
}
110
+ #endif
79
111
return unsafeBitCast ( ptr, to: T . self)
80
112
}
81
113
82
114
public func dlclose( _ handle: DLHandle ) throws {
83
115
try handle. close ( )
84
116
}
85
117
118
+ #if !os(Windows)
86
119
public func dlerror( ) -> String ? {
87
120
if let err: UnsafeMutablePointer < Int8 > = dlerror ( ) {
88
121
return String ( cString: err)
89
122
}
90
123
return nil
91
124
}
125
+ #endif
0 commit comments