text: import py
  from ctypes import *
  from support import BaseCTypesTestChecker
  
  # IMPORTANT INFO:
  #
  # Consider this call:
  #    func.restype = c_char_p
  #    func(c_char_p("123"))
  # It returns
  #    "123"
  #
  # WHY IS THIS SO?
  #
  # argument tuple (c_char_p("123"), ) is destroyed after the function
  # func is called, but NOT before the result is actually built.
  #
  # If the arglist would be destroyed BEFORE the result has been built,
  # the c_char_p("123") object would already have a zero refcount,
  # and the pointer passed to (and returned by) the function would
  # probably point to deallocated space.
  #
  # In this case, there would have to be an additional reference to the argument...
  
  def setup_module(mod):
      import conftest
      _ctypes_test = str(conftest.sofile)
      mod.testdll = CDLL(_ctypes_test)
  
  # Return machine address `a` as a (possibly long) non-negative integer.
  # Starting with Python 2.5, id(anything) is always non-negative, and
  # the ctypes addressof() inherits that via PyLong_FromVoidPtr().
  def positive_address(a):
      if a >= 0:
          return a
      # View the bits in `a` as unsigned instead.
      import struct
      num_bits = struct.calcsize("P") * 8 # num bits in native machine address
      a += 1L << num_bits
      assert a >= 0
      return a
  
  def c_wbuffer(init):
      n = len(init) + 1
      return (c_wchar * n)(*init)
  
  class TestCharPointers(BaseCTypesTestChecker):
  
      def test_int_pointer_arg(self):
          func = testdll._testfunc_p_p
          func.restype = c_long
          assert 0 == func(0)
  
          ci = c_int(0)
  
          func.argtypes = POINTER(c_int),
          assert positive_address(addressof(ci)) == (
                               positive_address(func(byref(ci))))
  
          func.argtypes = c_char_p,
          raises(ArgumentError, func, byref(ci))
  
          func.argtypes = POINTER(c_short),
          raises(ArgumentError, func, byref(ci))
  
          func.argtypes = POINTER(c_double),
          raises(ArgumentError, func, byref(ci))
  
      def test_POINTER_c_char_arg(self):
          func = testdll._testfunc_p_p
          func.restype = c_char_p
          func.argtypes = POINTER(c_char),
  
          assert None == func(None)
          assert "123" == func("123")
          assert None == func(c_char_p(None))
          assert "123" == func(c_char_p("123"))
  
          assert "123" == func(c_buffer("123"))
          ca = c_char("a")
          assert "a" == func(pointer(ca))[0]
          assert "a" == func(byref(ca))[0]
  
      def test_c_char_p_arg(self):
          func = testdll._testfunc_p_p
          func.restype = c_char_p
          func.argtypes = c_char_p,
  
          assert None == func(None)
          assert "123" == func("123")
          assert None == func(c_char_p(None))
          assert "123" == func(c_char_p("123"))
  
          assert "123" == func(c_buffer("123"))
          ca = c_char("a")
          assert "a" == func(pointer(ca))[0]
          assert "a" == func(byref(ca))[0]
  
      def test_c_void_p_arg(self):
          func = testdll._testfunc_p_p
          func.restype = c_char_p
          func.argtypes = c_void_p,
  
          assert None == func(None)
          assert "123" == func("123")
          assert "123" == func(c_char_p("123"))
          assert None == func(c_char_p(None))
  
          assert "123" == func(c_buffer("123"))
          ca = c_char("a")
          assert "a" == func(pointer(ca))[0]
          assert "a" == func(byref(ca))[0]
  
          func(byref(c_int()))
          func(pointer(c_int()))
          func((c_int * 3)())
  
          try:
              func.restype = c_wchar_p
          except NameError:
              pass
          else:
              assert None == func(c_wchar_p(None))
              assert u"123" == func(c_wchar_p(u"123"))
  
      def test_instance(self):
          func = testdll._testfunc_p_p
          func.restype = c_void_p
  
          class X:
              _as_parameter_ = None
  
          func.argtypes = c_void_p,
          assert None == func(X())
  
          func.argtypes = None
          assert None == func(X())
  
  try:
      c_wchar
  except NameError:
      pass
  else:
      class TestWCharPointers(BaseCTypesTestChecker):
  
          def setup_class(cls):
              func = testdll._testfunc_p_p
              func.restype = c_int
              func.argtypes = None
              cls.func = func
              BaseCTypesTestChecker.setup_class.im_func(cls)
  
  
          def test_POINTER_c_wchar_arg(self):
              func = self.func
              func.restype = c_wchar_p
              func.argtypes = POINTER(c_wchar),
  
              assert None == func(None)
              assert u"123" == func(u"123")
              assert None == func(c_wchar_p(None))
              assert u"123" == func(c_wchar_p(u"123"))
  
              assert u"123" == func(c_wbuffer(u"123"))
              ca = c_wchar("a")
              assert u"a" == func(pointer(ca))[0]
              assert u"a" == func(byref(ca))[0]
  
          def test_c_wchar_p_arg(self):
              func = self.func
              func.restype = c_wchar_p
              func.argtypes = c_wchar_p,
  
              c_wchar_p.from_param(u"123")
  
              assert None == func(None)
              assert "123" == func(u"123")
              assert None == func(c_wchar_p(None))
              assert "123" == func(c_wchar_p("123"))
  
              # XXX Currently, these raise TypeErrors, although they shouldn't:
              assert "123" == func(c_wbuffer("123"))
              ca = c_wchar("a")
              assert "a" == func(pointer(ca))[0]
              assert "a" == func(byref(ca))[0]
  
  class TestArray(BaseCTypesTestChecker):
      def test(self):
          func = testdll._testfunc_ai8
          func.restype = POINTER(c_int)
          func.argtypes = c_int * 8,
  
          func((c_int * 8)(1, 2, 3, 4, 5, 6, 7, 8))
  
          # This did crash before:
  
          def func(): pass
          CFUNCTYPE(None, c_int * 3)(func)
  
  ################################################################
  
  if __name__ == '__main__':
      unittest.main()
  