1
1
import os as _os , sys as _sys
2
+ import types as _types
2
3
4
+ from _ctypes import RTLD_LOCAL , RTLD_GLOBAL
3
5
from _ctypes import sizeof
4
6
from _ctypes import _SimpleCData
7
+ from _ctypes import CFuncPtr as _CFuncPtr
8
+
5
9
from struct import calcsize as _calcsize
6
10
11
+
12
+ DEFAULT_MODE = RTLD_LOCAL
13
+ if _os .name == "posix" and _sys .platform == "darwin" :
14
+ # On OS X 10.3, we use RTLD_GLOBAL as default mode
15
+ # because RTLD_LOCAL does not work at least on some
16
+ # libraries. OS X 10.3 is Darwin 7, so we check for
17
+ # that.
18
+
19
+ if int (_os .uname ().release .split ('.' )[0 ]) < 8 :
20
+ DEFAULT_MODE = RTLD_GLOBAL
21
+
22
+ from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL , \
23
+ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI , \
24
+ FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO , \
25
+ FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR
26
+
7
27
def create_string_buffer (init , size = None ):
8
28
"""create_string_buffer(aBytes) -> character array
9
29
create_string_buffer(anInteger) -> character array
@@ -131,3 +151,115 @@ class c_bool(_SimpleCData):
131
151
# s = create_string_buffer(b'\000' * 32)
132
152
assert i .value == 42
133
153
assert f .value == 3.14
154
+
155
+ if _os .name == "nt" :
156
+ from _ctypes import LoadLibrary as _dlopen
157
+ from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
158
+
159
+ class CDLL (object ):
160
+ """An instance of this class represents a loaded dll/shared
161
+ library, exporting functions using the standard C calling
162
+ convention (named 'cdecl' on Windows).
163
+
164
+ The exported functions can be accessed as attributes, or by
165
+ indexing with the function name. Examples:
166
+
167
+ <obj>.qsort -> callable object
168
+ <obj>['qsort'] -> callable object
169
+
170
+ Calling the functions releases the Python GIL during the call and
171
+ reacquires it afterwards.
172
+ """
173
+ _func_flags_ = _FUNCFLAG_CDECL
174
+ _func_restype_ = c_int
175
+ # default values for repr
176
+ _name = '<uninitialized>'
177
+ _handle = 0
178
+ _FuncPtr = None
179
+
180
+ def __init__ (self , name , mode = DEFAULT_MODE , handle = None ,
181
+ use_errno = False ,
182
+ use_last_error = False ,
183
+ winmode = None ):
184
+ self ._name = name
185
+ flags = self ._func_flags_
186
+ if use_errno :
187
+ flags |= _FUNCFLAG_USE_ERRNO
188
+ if use_last_error :
189
+ flags |= _FUNCFLAG_USE_LASTERROR
190
+ if _sys .platform .startswith ("aix" ):
191
+ """When the name contains ".a(" and ends with ")",
192
+ e.g., "libFOO.a(libFOO.so)" - this is taken to be an
193
+ archive(member) syntax for dlopen(), and the mode is adjusted.
194
+ Otherwise, name is presented to dlopen() as a file argument.
195
+ """
196
+ if name and name .endswith (")" ) and ".a(" in name :
197
+ mode |= ( _os .RTLD_MEMBER | _os .RTLD_NOW )
198
+ if _os .name == "nt" :
199
+ if winmode is not None :
200
+ mode = winmode
201
+ else :
202
+ import nt
203
+ mode = 4096
204
+ if '/' in name or '\\ ' in name :
205
+ self ._name = nt ._getfullpathname (self ._name )
206
+ mode |= nt ._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
207
+
208
+ class _FuncPtr (_CFuncPtr ):
209
+ _flags_ = flags
210
+ _restype_ = self ._func_restype_
211
+ self ._FuncPtr = _FuncPtr
212
+
213
+ if handle is None :
214
+ self ._handle = _dlopen (self ._name , mode )
215
+ else :
216
+ self ._handle = handle
217
+
218
+ def __repr__ (self ):
219
+ return "<%s '%s', handle %x at %#x>" % \
220
+ (self .__class__ .__name__ , self ._name ,
221
+ (self ._handle & (_sys .maxsize * 2 + 1 )),
222
+ id (self ) & (_sys .maxsize * 2 + 1 ))
223
+
224
+ def __getattr__ (self , name ):
225
+ if name .startswith ('__' ) and name .endswith ('__' ):
226
+ raise AttributeError (name )
227
+ func = self .__getitem__ (name )
228
+ setattr (self , name , func )
229
+ return func
230
+
231
+ def __getitem__ (self , name_or_ordinal ):
232
+ func = self ._FuncPtr ((name_or_ordinal , self ))
233
+ if not isinstance (name_or_ordinal , int ):
234
+ func .__name__ = name_or_ordinal
235
+ return func
236
+
237
+ class LibraryLoader (object ):
238
+ def __init__ (self , dlltype ):
239
+ self ._dlltype = dlltype
240
+
241
+ def __getattr__ (self , name ):
242
+ if name [0 ] == '_' :
243
+ raise AttributeError (name )
244
+ try :
245
+ dll = self ._dlltype (name )
246
+ except OSError :
247
+ raise AttributeError (name )
248
+ setattr (self , name , dll )
249
+ return dll
250
+
251
+ def __getitem__ (self , name ):
252
+ return getattr (self , name )
253
+
254
+ def LoadLibrary (self , name ):
255
+ return self ._dlltype (name )
256
+
257
+ __class_getitem__ = classmethod (_types .GenericAlias )
258
+
259
+ cdll = LibraryLoader (CDLL )
260
+
261
+ if _os .name == "posix" and _sys .platform == "darwin" :
262
+ pass
263
+ else :
264
+ libc = cdll .msvcrt
265
+ print (libc .rand ())
0 commit comments