diff -r 6f71208004cd pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py	Sat Apr 02 11:13:14 2011 +0200
+++ b/pypy/module/cpyext/api.py	Mon Apr 04 22:42:53 2011 +0200
@@ -37,7 +37,7 @@
 DEBUG_WRAPPER = True
 
 # update these for other platforms
-Py_ssize_t = lltype.Signed
+Py_ssize_t = lltype.Typedef(rffi.SSIZE_T, 'Py_ssize_t')
 Py_ssize_tP = rffi.CArrayPtr(Py_ssize_t)
 size_t = rffi.ULONG
 ADDR = lltype.Signed
@@ -192,16 +192,19 @@
     - set `external` to False to get a C function pointer, but not exported by
       the API headers.
     """
+    real_restype = restype if not isinstance(restype, lltype.Typedef) else restype._origtype
+    
     if error is _NOT_SPECIFIED:
-        if isinstance(restype, lltype.Ptr):
-            error = lltype.nullptr(restype.TO)
-        elif restype is lltype.Void:
+        if isinstance(real_restype, lltype.Ptr):
+            error = lltype.nullptr(real_restype.TO)
+        elif real_restype is lltype.Void:
             error = CANNOT_FAIL
     if type(error) is int:
-        error = rffi.cast(restype, error)
-    expect_integer = (isinstance(restype, lltype.Primitive) and
-                      rffi.cast(restype, 0) == 0)
+        error = rffi.cast(real_restype, error)
+    expect_integer = (isinstance(real_restype, lltype.Primitive) and
+                      rffi.cast(real_restype, 0) == 0)
 
+    
     def decorate(func):
         func_name = func.func_name
         if external:
diff -r 6f71208004cd pypy/module/cpyext/stringobject.py
--- a/pypy/module/cpyext/stringobject.py	Sat Apr 02 11:13:14 2011 +0200
+++ b/pypy/module/cpyext/stringobject.py	Mon Apr 04 22:42:53 2011 +0200
@@ -2,7 +2,7 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.module.cpyext.api import (
     cpython_api, cpython_struct, bootstrap_function, build_type_checkers,
-    PyObjectFields, Py_ssize_t, CONST_STRING)
+    PyObjectFields, Py_ssize_t, Py_ssize_tP, CONST_STRING)
 from pypy.module.cpyext.pyerrors import PyErr_BadArgument
 from pypy.module.cpyext.pyobject import (
     PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
@@ -138,7 +138,7 @@
         ref_str.c_buffer = rffi.str2charp(s)
     return ref_str.c_buffer
 
-@cpython_api([PyObject, rffi.CCHARPP, rffi.CArrayPtr(Py_ssize_t)], rffi.INT_real, error=-1)
+@cpython_api([PyObject, rffi.CCHARPP, Py_ssize_tP], rffi.INT_real, error=-1)
 def PyString_AsStringAndSize(space, ref, buffer, length):
     if not PyString_Check(space, ref):
         raise OperationError(space.w_TypeError, space.wrap(
diff -r 6f71208004cd pypy/rpython/lltypesystem/ll2ctypes.py
--- a/pypy/rpython/lltypesystem/ll2ctypes.py	Sat Apr 02 11:13:14 2011 +0200
+++ b/pypy/rpython/lltypesystem/ll2ctypes.py	Mon Apr 04 22:42:53 2011 +0200
@@ -255,6 +255,8 @@
         return cls
 
 def build_new_ctypes_type(T, delayed_builders):
+    if isinstance(T, lltype.Typedef):
+        T = T._origtype
     if isinstance(T, lltype.Ptr):
         if isinstance(T.TO, lltype.FuncType):
             argtypes = [get_ctypes_type(ARG) for ARG in T.TO.ARGS
@@ -758,6 +760,8 @@
     """
     if T is lltype.Void:
         return None
+    if isinstance(T, lltype.Typedef):
+        T = T._origtype
     if isinstance(T, lltype.Ptr):
         if not cobj or not ctypes.cast(cobj, ctypes.c_void_p).value:   # NULL pointer
             # CFunctionType.__nonzero__ is broken before Python 2.6
@@ -1092,6 +1096,8 @@
         value = value.adr
     if isinstance(value, llmemory.fakeaddress):
         value = value.ptr or 0
+    if isinstance(RESTYPE, lltype.Typedef):
+        RESTYPE = RESTYPE._origtype
     TYPE1 = lltype.typeOf(value)
     cvalue = lltype2ctypes(value)
     cresulttype = get_ctypes_type(RESTYPE)
diff -r 6f71208004cd pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py	Sat Apr 02 11:13:14 2011 +0200
+++ b/pypy/rpython/lltypesystem/lltype.py	Mon Apr 04 22:42:53 2011 +0200
@@ -95,6 +95,8 @@
     __slots__ = ['__dict__', '__cached_hash']
 
     def __eq__(self, other):
+        if isinstance(other, Typedef):
+            return other.__eq__(self)
         return self.__class__ is other.__class__ and (
             self is other or safe_equal(self.__dict__, other.__dict__))
 
@@ -194,6 +196,29 @@
         raise NotImplementedError
 
 
+class Typedef(LowLevelType):
+    """ A typedef is just another name for an existing type """
+    def __init__(self, type, c_name):
+        """ type is rffi type, cname is what we are in C land """
+        assert isinstance(type, LowLevelType)
+        self._origtype = type
+        self._c_name = c_name
+        
+    def __eq__(self, other):
+        return other == self._origtype
+        
+    def __getattr__(self, name):
+        return self._origtype.get(name)
+    
+    def _defl(self, parent=None, parentindex=None):
+        return self._origtype._defl()
+
+    def _allocate(self, initialization, parent=None, parentindex=None):
+        return self._origtype._allocate(initialization, parent, parentindex)
+
+    def __repr__(self):
+        return '<Typedef "%s" of %r>' % (self._c_name, self._origtype)
+
 class Struct(ContainerType):
     _gckind = 'raw'
 
diff -r 6f71208004cd pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py	Sat Apr 02 11:13:14 2011 +0200
+++ b/pypy/rpython/lltypesystem/rffi.py	Mon Apr 04 22:42:53 2011 +0200
@@ -818,6 +818,8 @@
     """Similar to llmemory.sizeof() but tries hard to return a integer
     instead of a symbolic value.
     """
+    if isinstance(tp, lltype.Typedef):
+        tp = tp._origtype
     if isinstance(tp, lltype.FixedSizeArray):
         return sizeof(tp.OF) * tp.length
     if isinstance(tp, lltype.Struct):
diff -r 6f71208004cd pypy/rpython/lltypesystem/test/test_lltype.py
--- a/pypy/rpython/lltypesystem/test/test_lltype.py	Sat Apr 02 11:13:14 2011 +0200
+++ b/pypy/rpython/lltypesystem/test/test_lltype.py	Mon Apr 04 22:42:53 2011 +0200
@@ -804,7 +804,16 @@
                  hints={'immutable_fields': FieldListAccessor({'x':'[*]'})})
     assert S._immutable_field('x') == '[*]'
 
-
+def test_typedef():
+    T = Typedef(Signed, 'T')
+    assert T == Signed
+    py.test.raises(TypeError, Ptr, T)
+    assert rffi.CArrayPtr(T) == rffi.CArrayPtr(Signed)
+    
+    F = FuncType((T,), T)
+    assert F.RESULT == Signed
+    assert F.ARGS == (Signed,)
+    
 class TestTrackAllocation:
     def test_automatic_tracking(self):
         # calls to start_tracking_allocations/stop_tracking_allocations
diff -r 6f71208004cd pypy/translator/c/database.py
--- a/pypy/translator/c/database.py	Sat Apr 02 11:13:14 2011 +0200
+++ b/pypy/translator/c/database.py	Mon Apr 04 22:42:53 2011 +0200
@@ -1,7 +1,7 @@
 from pypy.rpython.lltypesystem.lltype import \
      Primitive, Ptr, typeOf, RuntimeTypeInfo, \
      Struct, Array, FuncType, PyObject, Void, \
-     ContainerType, OpaqueType, FixedSizeArray, _uninitialized
+     ContainerType, OpaqueType, FixedSizeArray, _uninitialized, Typedef
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rpython.lltypesystem.llmemory import WeakRef, _WeakRefType, GCREF
 from pypy.rpython.lltypesystem.rffi import CConstant
@@ -100,6 +100,8 @@
     def gettype(self, T, varlength=1, who_asks=None, argnames=[]):
         if isinstance(T, Primitive) or T == GCREF:
             return PrimitiveType[T]
+        elif isinstance(T, Typedef):
+            return '%s @' % T._c_name
         elif isinstance(T, Ptr):
             if (isinstance(T.TO, OpaqueType) and
                 T.TO.hints.get('c_pointer_typedef') is not None):
