summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Heller <theller@ctypes.org>2006-04-21 16:51:04 (GMT)
committerThomas Heller <theller@ctypes.org>2006-04-21 16:51:04 (GMT)
commit6ff67ef09687611e810e20c23d5f7f7194693331 (patch)
tree744761a5838ca63fceb1f9a58597b74bd8c981b1
parent4b75a7c1cfb0aebd939fc17fccbcfc66ade4dea0 (diff)
downloadcpython-6ff67ef09687611e810e20c23d5f7f7194693331.zip
cpython-6ff67ef09687611e810e20c23d5f7f7194693331.tar.gz
cpython-6ff67ef09687611e810e20c23d5f7f7194693331.tar.bz2
Merge in changes from ctypes 0.9.9.6 upstream version.
-rw-r--r--Lib/ctypes/__init__.py36
-rw-r--r--Lib/ctypes/_loader.py262
-rw-r--r--Lib/ctypes/test/test_bitfields.py2
-rw-r--r--Lib/ctypes/test/test_byteswap.py2
-rw-r--r--Lib/ctypes/test/test_callbacks.py2
-rw-r--r--Lib/ctypes/test/test_cast.py27
-rw-r--r--Lib/ctypes/test/test_cfuncs.py2
-rw-r--r--Lib/ctypes/test/test_checkretval.py2
-rw-r--r--Lib/ctypes/test/test_find.py90
-rw-r--r--Lib/ctypes/test/test_funcptr.py2
-rw-r--r--Lib/ctypes/test/test_functions.py4
-rw-r--r--Lib/ctypes/test/test_libc.py2
-rw-r--r--Lib/ctypes/test/test_loading.py38
-rw-r--r--Lib/ctypes/test/test_pointers.py8
-rw-r--r--Lib/ctypes/test/test_posix.py40
-rw-r--r--Lib/ctypes/test/test_prototypes.py2
-rw-r--r--Lib/ctypes/test/test_refcounts.py2
-rw-r--r--Lib/ctypes/test/test_returnfuncptrs.py4
-rw-r--r--Lib/ctypes/test/test_slicing.py4
-rw-r--r--Lib/ctypes/test/test_stringptr.py2
-rw-r--r--Lib/ctypes/test/test_unicode.py4
-rw-r--r--Lib/ctypes/test/test_values.py4
-rw-r--r--Lib/ctypes/test/test_win32.py2
-rw-r--r--Lib/ctypes/util.py122
24 files changed, 300 insertions, 365 deletions
diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py
index 28ac180..f2ddbaa 100644
--- a/Lib/ctypes/__init__.py
+++ b/Lib/ctypes/__init__.py
@@ -3,7 +3,7 @@
import os as _os, sys as _sys
from itertools import chain as _chain
-__version__ = "0.9.9.4"
+__version__ = "0.9.9.6"
from _ctypes import Union, Structure, Array
from _ctypes import _Pointer
@@ -23,8 +23,6 @@ if _os.name in ("nt", "ce"):
from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI
-from ctypes._loader import LibraryLoader
-
"""
WINOLEAPI -> HRESULT
WINOLEAPI_(type)
@@ -72,9 +70,11 @@ def CFUNCTYPE(restype, *argtypes):
The function prototype can be called in three ways to create a
callable object:
- prototype(funct) - returns a C callable function calling funct
- prototype(vtbl_index, method_name[, paramflags]) - a Python callable that calls a COM method
- prototype(funct_name, dll[, paramflags]) - a Python callable that calls an exported function in a dll
+ prototype(integer address) -> foreign function
+ prototype(callable) -> create and return a C callable function from callable
+ prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
+ prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
+ prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
"""
try:
return _c_functype_cache[(restype, argtypes)]
@@ -352,6 +352,23 @@ if _os.name in ("nt", "ce"):
_flags_ = _FUNCFLAG_STDCALL
_restype_ = HRESULT
+class LibraryLoader(object):
+ def __init__(self, dlltype):
+ self._dlltype = dlltype
+
+ def __getattr__(self, name):
+ if name[0] == '_':
+ raise AttributeError(name)
+ dll = self._dlltype(name)
+ setattr(self, name, dll)
+ return dll
+
+ def __getitem__(self, name):
+ return getattr(self, name)
+
+ def LoadLibrary(self, name):
+ return self._dlltype(name)
+
cdll = LibraryLoader(CDLL)
pydll = LibraryLoader(PyDLL)
@@ -402,7 +419,12 @@ def PYFUNCTYPE(restype, *argtypes):
_restype_ = restype
_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
return CFunctionType
-cast = PYFUNCTYPE(py_object, c_void_p, py_object)(_cast_addr)
+_cast = PYFUNCTYPE(py_object, c_void_p, py_object)(_cast_addr)
+
+def cast(obj, typ):
+ result = _cast(obj, typ)
+ result.__keepref = obj
+ return result
_string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
def string_at(ptr, size=0):
diff --git a/Lib/ctypes/_loader.py b/Lib/ctypes/_loader.py
deleted file mode 100644
index 7a48c1c..0000000
--- a/Lib/ctypes/_loader.py
+++ /dev/null
@@ -1,262 +0,0 @@
-import sys, os
-import ctypes
-
-if os.name in ("nt", "ce"):
- from _ctypes import LoadLibrary as dlopen
-else:
- from _ctypes import dlopen
-from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
-
-# _findLib(name) returns an iterable of possible names for a library.
-if os.name in ("nt", "ce"):
- def _findLib(name):
- return [name]
-
-if os.name == "posix" and sys.platform == "darwin":
- from ctypes.macholib.dyld import dyld_find as _dyld_find
- def _findLib(name):
- possible = ['lib%s.dylib' % name,
- '%s.dylib' % name,
- '%s.framework/%s' % (name, name)]
- for name in possible:
- try:
- return [_dyld_find(name)]
- except ValueError:
- continue
- return []
-
-elif os.name == "posix":
- # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
- import re, tempfile
-
- def _findLib_gcc(name):
- expr = '[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
- cmd = 'if type gcc &>/dev/null; then CC=gcc; else CC=cc; fi;' \
- '$CC -Wl,-t -o /dev/null 2>&1 -l' + name
- try:
- fdout, outfile = tempfile.mkstemp()
- fd = os.popen(cmd)
- trace = fd.read()
- err = fd.close()
- finally:
- try:
- os.unlink(outfile)
- except OSError, e:
- if e.errno != errno.ENOENT:
- raise
- res = re.search(expr, trace)
- if not res:
- return None
- return res.group(0)
-
- def _findLib_ld(name):
- expr = '/[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
- res = re.search(expr, os.popen('/sbin/ldconfig -p 2>/dev/null').read())
- if not res:
- cmd = 'ldd %s 2>/dev/null' % sys.executable
- res = re.search(expr, os.popen(cmd).read())
- if not res:
- return None
- return res.group(0)
-
- def _get_soname(f):
- cmd = "objdump -p -j .dynamic 2>/dev/null " + f
- res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read())
- if not res:
- return f
- return res.group(1)
-
- def _findLib(name):
- lib = _findLib_ld(name)
- if not lib:
- lib = _findLib_gcc(name)
- if not lib:
- return [name]
- return [_get_soname(lib)]
-
-class LibraryLoader(object):
- """Loader for shared libraries.
-
- Shared libraries are accessed when compiling/linking a program,
- and when the program is run. The purpose of the 'find' method is
- to locate a library similar to what the compiler does (on machines
- with several versions of a shared library the most recent should
- be loaded), while 'load' acts like when the program is run, and
- uses the runtime loader directly. 'load_version' works like
- 'load' but tries to be platform independend (for cases where this
- makes sense). Loading via attribute access is a shorthand
- notation especially useful for interactive use."""
-
-
- def __init__(self, dlltype, mode=RTLD_LOCAL):
- """Create a library loader instance which loads libraries by
- creating an instance of 'dlltype'. 'mode' can be RTLD_LOCAL
- or RTLD_GLOBAL, it is ignored on Windows.
- """
- self._dlltype = dlltype
- self._mode = mode
-
- def load(self, libname, mode=None):
- """Load and return the library with the given libname. On
- most systems 'libname' is the filename of the shared library;
- when it's not a pathname it will be searched in a system
- dependend list of locations (on many systems additional search
- paths can be specified by an environment variable). Sometimes
- the extension (like '.dll' on Windows) can be omitted.
-
- 'mode' allows to override the default flags specified in the
- constructor, it is ignored on Windows.
- """
- if mode is None:
- mode = self._mode
- return self._load(libname, mode)
-
- def load_library(self, libname, mode=None):
- """Load and return the library with the given libname. This
- method passes the specified 'libname' directly to the
- platform's library loading function (dlopen, or LoadLibrary).
-
- 'mode' allows to override the default flags specified in the
- constructor, it is ignored on Windows.
- """
- if mode is None:
- mode = self._mode
- return self._dlltype(libname, mode)
-
- # alias name for backwards compatiblity
- LoadLibrary = load_library
-
- # Helpers for load and load_version - assembles a filename from name and filename
- if os.name in ("nt", "ce"):
- # Windows (XXX what about cygwin?)
- def _plat_load_version(self, name, version, mode):
- # not sure if this makes sense
- if version is not None:
- return self.load(name + version, mode)
- return self.load(name, mode)
-
- _load = load_library
-
- elif os.name == "posix" and sys.platform == "darwin":
- # Mac OS X
- def _plat_load_version(self, name, version, mode):
- if version:
- return self.load("lib%s.%s.dylib" % (name, version), mode)
- return self.load("lib%s.dylib" % name, mode)
-
- def _load(self, libname, mode):
- # _dyld_find raises ValueError, convert this into OSError
- try:
- pathname = _dyld_find(libname)
- except ValueError:
- raise OSError("Library %s could not be found" % libname)
- return self.load_library(pathname, mode)
-
- elif os.name == "posix":
- # Posix
- def _plat_load_version(self, name, version, mode):
- if version:
- return self.load("lib%s.so.%s" % (name, version), mode)
- return self.load("lib%s.so" % name, mode)
-
- _load = load_library
-
- else:
- # Others, TBD
- def _plat_load_version(self, name, version, mode=None):
- return self.load(name, mode)
-
- _load = load_library
-
- def load_version(self, name, version=None, mode=None):
- """Build a (system dependend) filename from 'name' and
- 'version', then load and return it. 'name' is the library
- name without any prefix like 'lib' and suffix like '.so' or
- '.dylib'. This method should be used if a library is
- available on different platforms, using the particular naming
- convention of each platform.
-
- 'mode' allows to override the default flags specified in the
- constructor, it is ignored on Windows.
- """
- return self._plat_load_version(name, version, mode)
-
- def find(self, name, mode=None):
- """Try to find a library, load and return it. 'name' is the
- library name without any prefix like 'lib', suffix like '.so',
- '.dylib' or version number (this is the form used for the
- posix linker option '-l').
-
- 'mode' allows to override the default flags specified in the
- constructor, it is ignored on Windows.
-
- On windows, this method does the same as the 'load' method.
-
- On other platforms, this function might call other programs
- like the compiler to find the library. When using ctypes to
- write a shared library wrapping, consider using .load() or
- .load_version() instead.
- """
- for libname in _findLib(name):
- try:
- return self.load(libname, mode)
- except OSError:
- continue
- raise OSError("Library %r not found" % name)
-
- def __getattr__(self, name):
- """Load a library via attribute access. Calls
- .load_version(). The result is cached."""
- if name.startswith("_"):
- raise AttributeError(name)
- dll = self.load_version(name)
- setattr(self, name, dll)
- return dll
-
-################################################################
-# test code
-
-class CDLL(object):
- def __init__(self, name, mode):
- self._handle = dlopen(name, mode)
- self._name = name
-
- def __repr__(self):
- return "<%s '%s', handle %x at %x>" % \
- (self.__class__.__name__, self._name,
- (self._handle & (sys.maxint*2 + 1)),
- id(self))
-
-cdll = LibraryLoader(CDLL)
-
-def test():
- if os.name == "nt":
- print cdll.msvcrt
- print cdll.load("msvcrt")
- # load_version looks more like an artefact:
- print cdll.load_version("msvcr", "t")
- print cdll.find("msvcrt")
-
- if os.name == "posix":
- # find and load_version
- print cdll.find("m")
- print cdll.find("c")
- print cdll.load_version("crypto", "0.9.7")
-
- # getattr
- print cdll.m
- print cdll.bz2
-
- # load
- if sys.platform == "darwin":
- print cdll.load("libm.dylib")
- print cdll.load("libcrypto.dylib")
- print cdll.load("libSystem.dylib")
- print cdll.load("System.framework/System")
- else:
- print cdll.load("libm.so")
- print cdll.load("libcrypt.so")
- print cdll.find("crypt")
-
-if __name__ == "__main__":
- test()
diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py
index 54ea839..92c4669 100644
--- a/Lib/ctypes/test/test_bitfields.py
+++ b/Lib/ctypes/test/test_bitfields.py
@@ -24,7 +24,7 @@ class BITS(Structure):
("R", c_short, 6),
("S", c_short, 7)]
-func = cdll.load(_ctypes_test.__file__).unpack_bitfields
+func = CDLL(_ctypes_test.__file__).unpack_bitfields
func.argtypes = POINTER(BITS), c_char
##for n in "ABCDEFGHIMNOPQRS":
diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py
index d0ada40..1f68992 100644
--- a/Lib/ctypes/test/test_byteswap.py
+++ b/Lib/ctypes/test/test_byteswap.py
@@ -15,7 +15,7 @@ def bin(s):
class Test(unittest.TestCase):
def X_test(self):
- print sys.byteorder
+ print >> sys.stderr, sys.byteorder
for i in range(32):
bits = BITS()
setattr(bits, "i%s" % i, 1)
diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py
index a6ee150..9d96a54 100644
--- a/Lib/ctypes/test/test_callbacks.py
+++ b/Lib/ctypes/test/test_callbacks.py
@@ -115,7 +115,7 @@ class SampleCallbacksTestCase(unittest.TestCase):
def test_integrate(self):
# Derived from some then non-working code, posted by David Foster
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
# The function prototype called by 'integrate': double func(double);
CALLBACK = CFUNCTYPE(c_double, c_double)
diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py
index 6f25feb..821ce3f 100644
--- a/Lib/ctypes/test/test_cast.py
+++ b/Lib/ctypes/test/test_cast.py
@@ -23,33 +23,24 @@ class Test(unittest.TestCase):
def test_address2pointer(self):
array = (c_int * 3)(42, 17, 2)
- # on AMD64, sizeof(int) == 4 and sizeof(void *) == 8.
- # By default, cast would convert a Python int (or long) into
- # a C int, which would be too short to represent a pointer
- # on this platform.
-
- # So we have to wrap the address into a c_void_p for this to work.
- #
- # XXX Better would be to hide the differences in the cast function.
address = addressof(array)
ptr = cast(c_void_p(address), POINTER(c_int))
self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
+ ptr = cast(address, POINTER(c_int))
+ self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
+
def test_ptr2array(self):
array = (c_int * 3)(42, 17, 2)
-## # Hm, already tested above.
-## ptr = cast(array, POINTER(c_int))
-## self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
+ from sys import getrefcount
-# print cast(addressof(array), c_int * 3)[:]
-## ptr = cast(addressof(ptr)
-
-## print ptr[0], ptr[1], ptr[2]
-## ptr = POINTER(c_int).from_address(addressof(array))
-## # XXX this crashes:
-## print ptr[0], ptr[1], ptr[2]
+ before = getrefcount(array)
+ ptr = cast(array, POINTER(c_int))
+ self.failUnlessEqual(getrefcount(array), before + 1)
+ del ptr
+ self.failUnlessEqual(getrefcount(array), before)
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/ctypes/test/test_cfuncs.py
index 6e0798d..9d8db1f 100644
--- a/Lib/ctypes/test/test_cfuncs.py
+++ b/Lib/ctypes/test/test_cfuncs.py
@@ -7,7 +7,7 @@ from ctypes import *
import _ctypes_test
class CFunctions(unittest.TestCase):
- _dll = cdll.load(_ctypes_test.__file__)
+ _dll = CDLL(_ctypes_test.__file__)
def S(self):
return c_longlong.in_dll(self._dll, "last_tf_arg_s").value
diff --git a/Lib/ctypes/test/test_checkretval.py b/Lib/ctypes/test/test_checkretval.py
index 344d0bc..e055c49 100644
--- a/Lib/ctypes/test/test_checkretval.py
+++ b/Lib/ctypes/test/test_checkretval.py
@@ -14,7 +14,7 @@ class Test(unittest.TestCase):
def test_checkretval(self):
import _ctypes_test
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
self.failUnlessEqual(42, dll._testfunc_p_p(42))
dll._testfunc_p_p.restype = CHECKED
diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py
new file mode 100644
index 0000000..54c663c
--- /dev/null
+++ b/Lib/ctypes/test/test_find.py
@@ -0,0 +1,90 @@
+import unittest
+import os, sys
+from ctypes import *
+from ctypes.util import find_library
+from ctypes.test import is_resource_enabled
+
+if sys.platform == "win32":
+ lib_gl = find_library("OpenGL32")
+ lib_glu = find_library("Glu32")
+ lib_glut = find_library("glut32")
+ lib_gle = None
+elif sys.platform == "darwin":
+ lib_gl = lib_glu = find_library("OpenGL")
+ lib_glut = find_library("GLUT")
+ lib_gle = None
+else:
+ lib_gl = find_library("GL")
+ lib_glu = find_library("GLU")
+ lib_glut = find_library("glut")
+ lib_gle = find_library("gle")
+
+## print, for debugging
+if is_resource_enabled("printing"):
+ if lib_gl or lib_glu or lib_glut or lib_gle:
+ print "OpenGL libraries:"
+ for item in (("GL", lib_gl),
+ ("GLU", lib_glu),
+ ("glut", lib_glut),
+ ("gle", lib_gle)):
+ print "\t", item
+
+
+# On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode.
+class Test_OpenGL_libs(unittest.TestCase):
+ def setUp(self):
+ self.gl = self.glu = self.gle = self.glut = None
+ if lib_gl:
+ self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL)
+ if lib_glu:
+ self.glu = CDLL(lib_glu, RTLD_GLOBAL)
+ if lib_glut:
+ self.glut = CDLL(lib_glut)
+ if lib_gle:
+ self.gle = CDLL(lib_gle)
+
+ if lib_gl:
+ def test_gl(self):
+ if self.gl:
+ self.gl.glClearIndex
+
+ if lib_glu:
+ def test_glu(self):
+ if self.glu:
+ self.glu.gluBeginCurve
+
+ if lib_glut:
+ def test_glut(self):
+ if self.glut:
+ self.glut.glutWireTetrahedron
+
+ if lib_gle:
+ def test_gle(self):
+ if self.gle:
+ self.gle.gleGetJoinStyle
+
+##if os.name == "posix" and sys.platform != "darwin":
+
+## # On platforms where the default shared library suffix is '.so',
+## # at least some libraries can be loaded as attributes of the cdll
+## # object, since ctypes now tries loading the lib again
+## # with '.so' appended of the first try fails.
+## #
+## # Won't work for libc, unfortunately. OTOH, it isn't
+## # needed for libc since this is already mapped into the current
+## # process (?)
+## #
+## # On MAC OSX, it won't work either, because dlopen() needs a full path,
+## # and the default suffix is either none or '.dylib'.
+
+## class LoadLibs(unittest.TestCase):
+## def test_libm(self):
+## import math
+## libm = cdll.libm
+## sqrt = libm.sqrt
+## sqrt.argtypes = (c_double,)
+## sqrt.restype = c_double
+## self.failUnlessEqual(sqrt(2), math.sqrt(2))
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/Lib/ctypes/test/test_funcptr.py b/Lib/ctypes/test/test_funcptr.py
index 89b93c4..7ea873f 100644
--- a/Lib/ctypes/test/test_funcptr.py
+++ b/Lib/ctypes/test/test_funcptr.py
@@ -8,7 +8,7 @@ except NameError:
WINFUNCTYPE = CFUNCTYPE
import _ctypes_test
-lib = cdll.load(_ctypes_test.__file__)
+lib = CDLL(_ctypes_test.__file__)
class CFuncPtrTestCase(unittest.TestCase):
def test_basic(self):
diff --git a/Lib/ctypes/test/test_functions.py b/Lib/ctypes/test/test_functions.py
index ada9def..bfa0cad 100644
--- a/Lib/ctypes/test/test_functions.py
+++ b/Lib/ctypes/test/test_functions.py
@@ -15,9 +15,9 @@ except NameError:
WINFUNCTYPE = CFUNCTYPE
import _ctypes_test
-dll = cdll.load(_ctypes_test.__file__)
+dll = CDLL(_ctypes_test.__file__)
if sys.platform == "win32":
- windll = windll.load(_ctypes_test.__file__)
+ windll = WinDLL(_ctypes_test.__file__)
class POINT(Structure):
_fields_ = [("x", c_int), ("y", c_int)]
diff --git a/Lib/ctypes/test/test_libc.py b/Lib/ctypes/test/test_libc.py
index 8fd2789..c39f350 100644
--- a/Lib/ctypes/test/test_libc.py
+++ b/Lib/ctypes/test/test_libc.py
@@ -4,7 +4,7 @@ import unittest
from ctypes import *
import _ctypes_test
-lib = cdll.load(_ctypes_test.__file__)
+lib = CDLL(_ctypes_test.__file__)
class LibTest(unittest.TestCase):
def test_sqrt(self):
diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py
index 4558417..45585ae 100644
--- a/Lib/ctypes/test/test_loading.py
+++ b/Lib/ctypes/test/test_loading.py
@@ -1,6 +1,8 @@
from ctypes import *
import sys, unittest
import os, StringIO
+from ctypes.util import find_library
+from ctypes.test import is_resource_enabled
libc_name = None
if os.name == "nt":
@@ -18,39 +20,49 @@ else:
libc_name = line.split()[4]
else:
libc_name = line.split()[2]
-## print "libc_name is", libc_name
break
+if is_resource_enabled("printing"):
+ print "libc_name is", libc_name
+
class LoaderTest(unittest.TestCase):
unknowndll = "xxrandomnamexx"
if libc_name is not None:
def test_load(self):
- cdll.load(libc_name)
- cdll.load(os.path.basename(libc_name))
- self.assertRaises(OSError, cdll.load, self.unknowndll)
+ CDLL(libc_name)
+ CDLL(os.path.basename(libc_name))
+ self.assertRaises(OSError, CDLL, self.unknowndll)
if libc_name is not None and os.path.basename(libc_name) == "libc.so.6":
def test_load_version(self):
- cdll.load_version("c", "6")
+ cdll.LoadLibrary("libc.so.6")
# linux uses version, libc 9 should not exist
- self.assertRaises(OSError, cdll.load_version, "c", "9")
- self.assertRaises(OSError, cdll.load_version, self.unknowndll, "")
+ self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
+ self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll)
- def test_find(self):
- name = "c"
- cdll.find(name)
- self.assertRaises(OSError, cdll.find, self.unknowndll)
+ def test_find(self):
+ for name in ("c", "m"):
+ lib = find_library(name)
+ if lib:
+ cdll.LoadLibrary(lib)
+ CDLL(lib)
if os.name in ("nt", "ce"):
def test_load_library(self):
+ if is_resource_enabled("printing"):
+ print find_library("kernel32")
+ print find_library("user32")
+
if os.name == "nt":
- windll.load_library("kernel32").GetModuleHandleW
+ windll.kernel32.GetModuleHandleW
+ windll["kernel32"].GetModuleHandleW
windll.LoadLibrary("kernel32").GetModuleHandleW
WinDLL("kernel32").GetModuleHandleW
elif os.name == "ce":
- windll.load_library("coredll").GetModuleHandleW
+ windll.coredll.GetModuleHandleW
+ windll["coredll"].GetModuleHandleW
windll.LoadLibrary("coredll").GetModuleHandleW
WinDLL("coredll").GetModuleHandleW
diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py
index 3a324a6..c81c6c9 100644
--- a/Lib/ctypes/test/test_pointers.py
+++ b/Lib/ctypes/test/test_pointers.py
@@ -20,7 +20,7 @@ class PointersTestCase(unittest.TestCase):
self.failUnlessRaises(TypeError, A, c_ulong(33))
def test_pass_pointers(self):
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
func = dll._testfunc_p_p
func.restype = c_long
@@ -35,7 +35,7 @@ class PointersTestCase(unittest.TestCase):
self.failUnlessEqual(res[0], 12345678)
def test_change_pointers(self):
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
func = dll._testfunc_p_p
i = c_int(87654)
@@ -70,7 +70,7 @@ class PointersTestCase(unittest.TestCase):
return 0
callback = PROTOTYPE(func)
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
# This function expects a function pointer,
# and calls this with an integer pointer as parameter.
# The int pointer points to a table containing the numbers 1..10
@@ -156,7 +156,7 @@ class PointersTestCase(unittest.TestCase):
def test_charpp( self ):
"""Test that a character pointer-to-pointer is correctly passed"""
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
func = dll._testfunc_c_p_p
func.restype = c_char_p
argv = (c_char_p * 2)()
diff --git a/Lib/ctypes/test/test_posix.py b/Lib/ctypes/test/test_posix.py
deleted file mode 100644
index fe0a40a..0000000
--- a/Lib/ctypes/test/test_posix.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import unittest, os, sys
-from ctypes import *
-
-if os.name == "posix" and sys.platform == "linux2":
- # I don't really know on which platforms this works,
- # later it should use the find_library stuff to avoid
- # hardcoding the names.
-
- class TestRTLD_GLOBAL(unittest.TestCase):
- def test_GL(self):
- if os.path.exists('/usr/lib/libGL.so'):
- cdll.load('libGL.so', mode=RTLD_GLOBAL)
- if os.path.exists('/usr/lib/libGLU.so'):
- cdll.load('libGLU.so')
-
-##if os.name == "posix" and sys.platform != "darwin":
-
-## # On platforms where the default shared library suffix is '.so',
-## # at least some libraries can be loaded as attributes of the cdll
-## # object, since ctypes now tries loading the lib again
-## # with '.so' appended of the first try fails.
-## #
-## # Won't work for libc, unfortunately. OTOH, it isn't
-## # needed for libc since this is already mapped into the current
-## # process (?)
-## #
-## # On MAC OSX, it won't work either, because dlopen() needs a full path,
-## # and the default suffix is either none or '.dylib'.
-
-## class LoadLibs(unittest.TestCase):
-## def test_libm(self):
-## import math
-## libm = cdll.libm
-## sqrt = libm.sqrt
-## sqrt.argtypes = (c_double,)
-## sqrt.restype = c_double
-## self.failUnlessEqual(sqrt(2), math.sqrt(2))
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/ctypes/test/test_prototypes.py
index 47f5da1..aaaa47a 100644
--- a/Lib/ctypes/test/test_prototypes.py
+++ b/Lib/ctypes/test/test_prototypes.py
@@ -22,7 +22,7 @@ import unittest
# In this case, there would have to be an additional reference to the argument...
import _ctypes_test
-testdll = cdll.load(_ctypes_test.__file__)
+testdll = CDLL(_ctypes_test.__file__)
# Return machine address `a` as a (possibly long) non-negative integer.
# Starting with Python 2.5, id(anything) is always non-negative, and
diff --git a/Lib/ctypes/test/test_refcounts.py b/Lib/ctypes/test/test_refcounts.py
index 0c62bf2..448f292 100644
--- a/Lib/ctypes/test/test_refcounts.py
+++ b/Lib/ctypes/test/test_refcounts.py
@@ -6,7 +6,7 @@ MyCallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
OtherCallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_ulonglong)
import _ctypes_test
-dll = ctypes.cdll.load(_ctypes_test.__file__)
+dll = ctypes.CDLL(_ctypes_test.__file__)
class RefcountTestCase(unittest.TestCase):
diff --git a/Lib/ctypes/test/test_returnfuncptrs.py b/Lib/ctypes/test/test_returnfuncptrs.py
index ef1f6fd..88dccf2 100644
--- a/Lib/ctypes/test/test_returnfuncptrs.py
+++ b/Lib/ctypes/test/test_returnfuncptrs.py
@@ -8,7 +8,7 @@ class ReturnFuncPtrTestCase(unittest.TestCase):
def test_with_prototype(self):
# The _ctypes_test shared lib/dll exports quite some functions for testing.
# The get_strchr function returns a *pointer* to the C strchr function.
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
get_strchr = dll.get_strchr
get_strchr.restype = CFUNCTYPE(c_char_p, c_char_p, c_char)
strchr = get_strchr()
@@ -18,7 +18,7 @@ class ReturnFuncPtrTestCase(unittest.TestCase):
self.assertRaises(TypeError, strchr, "abcdef")
def test_without_prototype(self):
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
get_strchr = dll.get_strchr
# the default 'c_int' would not work on systems where sizeof(int) != sizeof(void *)
get_strchr.restype = c_void_p
diff --git a/Lib/ctypes/test/test_slicing.py b/Lib/ctypes/test/test_slicing.py
index 306c585..44d0b11 100644
--- a/Lib/ctypes/test/test_slicing.py
+++ b/Lib/ctypes/test/test_slicing.py
@@ -37,7 +37,7 @@ class SlicesTestCase(unittest.TestCase):
def test_char_ptr(self):
s = "abcdefghijklmnopqrstuvwxyz\0"
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
dll.my_strdup.restype = POINTER(c_char)
res = dll.my_strdup(s)
self.failUnlessEqual(res[:len(s)], s)
@@ -65,7 +65,7 @@ class SlicesTestCase(unittest.TestCase):
def test_wchar_ptr(self):
s = u"abcdefghijklmnopqrstuvwxyz\0"
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
dll.my_wcsdup.restype = POINTER(c_wchar)
dll.my_wcsdup.argtypes = POINTER(c_wchar),
res = dll.my_wcsdup(s)
diff --git a/Lib/ctypes/test/test_stringptr.py b/Lib/ctypes/test/test_stringptr.py
index 183a60c..6ee6ae0 100644
--- a/Lib/ctypes/test/test_stringptr.py
+++ b/Lib/ctypes/test/test_stringptr.py
@@ -3,7 +3,7 @@ from ctypes import *
import _ctypes_test
-lib = cdll.load(_ctypes_test.__file__)
+lib = CDLL(_ctypes_test.__file__)
class StringPtrTestCase(unittest.TestCase):
diff --git a/Lib/ctypes/test/test_unicode.py b/Lib/ctypes/test/test_unicode.py
index bb39746..78c5cf8 100644
--- a/Lib/ctypes/test/test_unicode.py
+++ b/Lib/ctypes/test/test_unicode.py
@@ -8,7 +8,7 @@ except AttributeError:
pass
else:
import _ctypes_test
- dll = ctypes.cdll.load(_ctypes_test.__file__)
+ dll = ctypes.CDLL(_ctypes_test.__file__)
wcslen = dll.my_wcslen
wcslen.argtypes = [ctypes.c_wchar_p]
@@ -66,7 +66,7 @@ else:
self.failUnlessEqual(buf[:], u"ab\0\0\0\0")
import _ctypes_test
- func = ctypes.cdll.load(_ctypes_test.__file__)._testfunc_p_p
+ func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
class StringTestCase(UnicodeTestCase):
def setUp(self):
diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py
index 1f25f9b..7ba3e21 100644
--- a/Lib/ctypes/test/test_values.py
+++ b/Lib/ctypes/test/test_values.py
@@ -10,7 +10,7 @@ import _ctypes_test
class ValuesTestCase(unittest.TestCase):
def test_an_integer(self):
- ctdll = cdll.load(_ctypes_test.__file__)
+ ctdll = CDLL(_ctypes_test.__file__)
an_integer = c_int.in_dll(ctdll, "an_integer")
x = an_integer.value
self.failUnlessEqual(x, ctdll.get_an_integer())
@@ -18,7 +18,7 @@ class ValuesTestCase(unittest.TestCase):
self.failUnlessEqual(x*2, ctdll.get_an_integer())
def test_undefined(self):
- ctdll = cdll.load(_ctypes_test.__file__)
+ ctdll = CDLL(_ctypes_test.__file__)
self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
class Win_ValuesTestCase(unittest.TestCase):
diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py
index 3d0b825..8247d37 100644
--- a/Lib/ctypes/test/test_win32.py
+++ b/Lib/ctypes/test/test_win32.py
@@ -54,7 +54,7 @@ class Structures(unittest.TestCase):
("right", c_long),
("bottom", c_long)]
- dll = cdll.load(_ctypes_test.__file__)
+ dll = CDLL(_ctypes_test.__file__)
pt = POINT(10, 10)
rect = RECT(0, 0, 20, 20)
diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py
new file mode 100644
index 0000000..4b8057e
--- /dev/null
+++ b/Lib/ctypes/util.py
@@ -0,0 +1,122 @@
+import sys, os
+import ctypes
+
+# find_library(name) returns the pathname of a library, or None.
+if os.name == "nt":
+ def find_library(name):
+ # See MSDN for the REAL search order.
+ for directory in os.environ['PATH'].split(os.pathsep):
+ fname = os.path.join(directory, name)
+ if os.path.exists(fname):
+ return fname
+ if fname.lower().endswith(".dll"):
+ continue
+ fname = fname + ".dll"
+ if os.path.exists(fname):
+ return fname
+ return None
+
+if os.name == "ce":
+ # search path according to MSDN:
+ # - absolute path specified by filename
+ # - The .exe launch directory
+ # - the Windows directory
+ # - ROM dll files (where are they?)
+ # - OEM specified search path: HKLM\Loader\SystemPath
+ def find_library(name):
+ return name
+
+if os.name == "posix" and sys.platform == "darwin":
+ from ctypes.macholib.dyld import dyld_find as _dyld_find
+ def find_library(name):
+ possible = ['lib%s.dylib' % name,
+ '%s.dylib' % name,
+ '%s.framework/%s' % (name, name)]
+ for name in possible:
+ try:
+ return _dyld_find(name)
+ except ValueError:
+ continue
+ return None
+
+elif os.name == "posix":
+ # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
+ import re, tempfile
+
+ def _findLib_gcc(name):
+ expr = '[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
+ cmd = 'if type gcc &>/dev/null; then CC=gcc; else CC=cc; fi;' \
+ '$CC -Wl,-t -o /dev/null 2>&1 -l' + name
+ try:
+ fdout, outfile = tempfile.mkstemp()
+ fd = os.popen(cmd)
+ trace = fd.read()
+ err = fd.close()
+ finally:
+ try:
+ os.unlink(outfile)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+ res = re.search(expr, trace)
+ if not res:
+ return None
+ return res.group(0)
+
+ def _findLib_ld(name):
+ expr = '/[^\(\)\s]*lib%s\.[^\(\)\s]*' % name
+ res = re.search(expr, os.popen('/sbin/ldconfig -p 2>/dev/null').read())
+ if not res:
+ # Hm, this works only for libs needed by the python executable.
+ cmd = 'ldd %s 2>/dev/null' % sys.executable
+ res = re.search(expr, os.popen(cmd).read())
+ if not res:
+ return None
+ return res.group(0)
+
+ def _get_soname(f):
+ cmd = "objdump -p -j .dynamic 2>/dev/null " + f
+ res = re.search(r'\sSONAME\s+([^\s]+)', os.popen(cmd).read())
+ if not res:
+ return None
+ return res.group(1)
+
+ def find_library(name):
+ lib = _findLib_ld(name) or _findLib_gcc(name)
+ if not lib:
+ return None
+ return _get_soname(lib)
+
+################################################################
+# test code
+
+def test():
+ from ctypes import cdll
+ if os.name == "nt":
+ print cdll.msvcrt
+ print cdll.load("msvcrt")
+ print find_library("msvcrt")
+
+ if os.name == "posix":
+ # find and load_version
+ print find_library("m")
+ print find_library("c")
+ print find_library("bz2")
+
+ # getattr
+## print cdll.m
+## print cdll.bz2
+
+ # load
+ if sys.platform == "darwin":
+ print cdll.LoadLibrary("libm.dylib")
+ print cdll.LoadLibrary("libcrypto.dylib")
+ print cdll.LoadLibrary("libSystem.dylib")
+ print cdll.LoadLibrary("System.framework/System")
+ else:
+ print cdll.LoadLibrary("libm.so")
+ print cdll.LoadLibrary("libcrypt.so")
+ print find_library("crypt")
+
+if __name__ == "__main__":
+ test()