diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index 1198b1c10531b6f8395fc5bd2736881686628068..c50cf3fb2a8e86d107f28e4f3419dc1c519baf29 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -167,16 +167,25 @@ def _handle_error(error):
     raise klass(_ffi.string(error.routine), error.code, _ffi.string(error.msg))
 # }}}
 
-class EQUALITY_TESTS(object):
+class _Common(object):
     def __eq__(self, other):
         return hash(self) == hash(other)
 
-class Device(EQUALITY_TESTS):
-    def __init__(self):
-        pass
-
     def __hash__(self):
-        return _lib.device__hash(self.ptr)
+        return getattr(_lib, '%s__hash' % self._id)(self.ptr)
+
+    @property
+    def int_ptr(self):
+        return getattr(_lib, '%s__int_ptr' % self._id)(self.ptr)
+
+    @classmethod
+    def from_int_ptr(cls, int_ptr_value):
+        ptr = _ffi.new('void **')
+        getattr(_lib, '%s__from_int_ptr' % cls._id)(ptr, int_ptr_value)
+        return _create_instance(cls, ptr[0])
+        
+class Device(_Common):
+    _id = 'device'
 
     # todo: __del__
 
@@ -187,11 +196,6 @@ class Device(EQUALITY_TESTS):
         _handle_error(_lib.device__get_info(self.ptr, param, info))
         return _generic_info_to_python(info)
 
-def _create_device(ptr):
-    device = Device()
-    device.ptr = ptr
-    return device
-
 def _parse_context_properties(properties):
     props = []
     if properties is None:
@@ -211,7 +215,9 @@ def _parse_context_properties(properties):
     return _ffi.new('cl_context_properties[]', props)
 
         
-class Context(EQUALITY_TESTS):
+class Context(_Common):
+    _id = 'context'
+
     def __init__(self, devices=None, properties=None, dev_type=None):
         c_props = _parse_context_properties(properties)
         status_code = _ffi.new('cl_int *')
@@ -228,14 +234,12 @@ class Context(EQUALITY_TESTS):
             raise NotImplementedError()
 
         self.ptr = ptr_ctx[0]
-
-    def __hash__(self):
-        return _lib.context__hash(self.ptr)
         
     def get_info(self, param):
         return 'TODO'
 
-class CommandQueue(EQUALITY_TESTS):
+class CommandQueue(_Common):
+    _id = 'command_queue'
     def __init__(self, context, device=None, properties=None):
         if properties is None:
             properties = 0
@@ -243,14 +247,11 @@ class CommandQueue(EQUALITY_TESTS):
         _handle_error(_lib._create_command_queue(ptr_command_queue, context.ptr, _ffi.NULL if device is None else device.ptr, properties))
         self.ptr = ptr_command_queue[0]
 
-    def __hash__(self):
-        return _lib.command_queue__hash(self.ptr)
-
     def get_info(self, param):
         print param
         raise NotImplementedError()
 
-class MemoryObjectHolder(EQUALITY_TESTS):
+class MemoryObjectHolder(_Common):
     def get_info(self, param):
         info = _ffi.new('generic_info *')
         _handle_error(_lib.memory_object_holder__get_info(self.ptr, param, info))
@@ -263,6 +264,8 @@ class MemoryObject(MemoryObjectHolder):
     pass
         
 class Buffer(MemoryObjectHolder):
+    _id = 'buffer'
+    
     @classmethod
     def _c_buffer_from_obj(cls, obj):
         # assume numpy array for now
@@ -285,22 +288,14 @@ class Buffer(MemoryObjectHolder):
         _handle_error(_lib._create_buffer(ptr_buffer, context.ptr, flags, size, c_hostbuf))
         self.ptr = ptr_buffer[0]
 
-class _Program(object):
+class _Program(_Common):
+    _id = 'program'
     def __init__(self, *args):
         if len(args) == 2:
             self._init_source(*args)
         else:
             self._init_binary(*args)
 
-    def __hash__(self):
-        return _lib.program__hash(self.ptr)
-
-    def int_ptr(self):
-        raise NotImplementedError()
-
-    def from_int_ptr(self, int_ptr_value):
-        raise NotImplementedError()
-            
     def _init_source(self, context, src):
         ptr_program = _ffi.new('void **')
         _handle_error(_lib._create_program_with_source(ptr_program, context.ptr, _ffi.new('char[]', src)))
@@ -348,7 +343,7 @@ class _Program(object):
             for i in xrange(devices.size[0]):
                 # TODO why is the cast needed? 
                 device_ptr = _ffi.cast('void**', devices.ptr[0])[i]
-                result.append(_create_device(device_ptr))
+                result.append(_create_instance(Device, device_ptr))
             return result
         elif param == program_info.BINARIES:
             ptr_binaries = _CArrays(_ffi.new('char***'))
@@ -361,13 +356,8 @@ class _Program(object):
         return _generic_info_to_python(info)
 
         
-class Platform(EQUALITY_TESTS):
-    def __init__(self):
-        pass
-
-    def __hash__(self):
-        return _lib.platform__hash(self.ptr)
-
+class Platform(_Common):
+    _id = 'platform'
     # todo: __del__
 
     def get_info(self, param):
@@ -382,17 +372,13 @@ class Platform(EQUALITY_TESTS):
         for i in xrange(devices.size[0]):
             # TODO why is the cast needed? 
             device_ptr = _ffi.cast('void**', devices.ptr[0])[i]
-            result.append(_create_device(device_ptr))
+            result.append(_create_instance(Device, device_ptr))
         # TODO remove, should be done via get_info(PLATFORM)
         for r in result:
             r.__dict__["platform"] = self
         return result
 
-def _create_platform(ptr):
-    platform = Platform()
-    platform.ptr = ptr
-    return platform
-
+        
 def _generic_info_to_python(info):
     if info.type == _lib.generic_info_type_chars:
         return _ffi.string(info.value._chars)
@@ -411,13 +397,12 @@ def _generic_info_to_python(info):
     raise NotImplementedError(info.type)
 
 class Kernel(object):
+    _id = 'kernel'
+    
     def __init__(self, program, name):
         ptr_kernel = _ffi.new('void **')
         _handle_error(_lib._create_kernel(ptr_kernel, program.ptr, name))
         self.ptr = ptr_kernel[0]
-
-    def __hash__(self):
-        return _lib.kernel__hash(self.ptr)
         
     def get_info(self, param):
         info = _ffi.new('generic_info *')
@@ -438,25 +423,18 @@ def get_platforms():
     for i in xrange(platforms.size[0]):
         # TODO why is the cast needed? 
         platform_ptr = _ffi.cast('void**', platforms.ptr[0])[i]
-        result.append(_create_platform(platform_ptr))
+        result.append(_create_instance(Platform, platform_ptr))
         
     return result
 
-class Event(EQUALITY_TESTS):
+class Event(_Common):
+    _id = 'event'
     def __init__(self):
         pass
         
-    def __hash__(self):
-        return _lib.event__hash(self.ptr)
-
     def get_info(self, param):
         print param
         raise NotImplementedError()
-    
-def _create_event(ptr):
-    event = Event()
-    event.ptr = ptr
-    return event
 
 
 def enqueue_nd_range_kernel(queue, kernel, global_work_size, local_work_size, global_work_offset=None, wait_for=None, g_times_l=False):
@@ -502,7 +480,7 @@ def enqueue_nd_range_kernel(queue, kernel, global_work_size, local_work_size, gl
         c_global_work_size,
         c_local_work_size
     ))
-    return _create_event(ptr_event[0])
+    return _create_instance(Event, ptr_event[0])
 
 def _enqueue_read_buffer(cq, mem, buf, device_offset=0, is_blocking=True):
     # assume numpy
@@ -518,4 +496,10 @@ def _enqueue_read_buffer(cq, mem, buf, device_offset=0, is_blocking=True):
         device_offset,
         bool(is_blocking)
     ))
-    return _create_event(ptr_event[0])
+    return _create_instance(Event, ptr_event[0])
+
+def _create_instance(cls, ptr):
+    ins = cls.__new__(cls)
+    ins.ptr = ptr
+    return ins
+    
diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp
index eb0dea0ac3d06ecfade28910d1851c9ce3edfa5a..f0bf5989a9f89978654ed68cc48ecc9423e27056 100644
--- a/src/c_wrapper/wrap_cl.cpp
+++ b/src/c_wrapper/wrap_cl.cpp
@@ -2214,12 +2214,71 @@ inline event *enqueue_nd_range_kernel(
     return 0;
   }
   
-  ::error *memory_object_holder__get_info(void *ptr_memory_object_holder, cl_mem_info param, generic_info *out) {
-    C_HANDLE_ERROR(
-    *out = static_cast<memory_object_holder*>(ptr_memory_object_holder)->get_info(param);
-		   )
+::error *memory_object_holder__get_info(void *ptr_memory_object_holder, cl_mem_info param, generic_info *out) {
+  C_HANDLE_ERROR(
+		 *out = static_cast<memory_object_holder*>(ptr_memory_object_holder)->get_info(param);
+		 )
     return 0;
   }
+
+
+intptr_t platform__int_ptr(void* ptr) {
+  return (intptr_t)(static_cast<platform*>(ptr)->data());
+}
+intptr_t kernel__int_ptr(void* ptr) {
+  return (intptr_t)(static_cast<kernel*>(ptr)->data());
+}
+intptr_t context__int_ptr(void* ptr) {
+  return (intptr_t)(static_cast<context*>(ptr)->data());
+}
+intptr_t command_queue__int_ptr(void* ptr) {
+  return (intptr_t)(static_cast<command_queue*>(ptr)->data());
+}
+intptr_t buffer__int_ptr(void* ptr) {
+  return (intptr_t)(static_cast<buffer*>(ptr)->data());
+}
+intptr_t program__int_ptr(void* ptr) {
+  return (intptr_t)(static_cast<program*>(ptr)->data());
+}
+intptr_t event__int_ptr(void* ptr) {
+  return (intptr_t)(static_cast<event*>(ptr)->data());
+}
+
+void *platform__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) {
+  C_HANDLE_ERROR(*ptr_out = new platform((cl_platform_id)int_ptr_value, /* retain */ true);)
+    return 0;
+}
+
+void *kernel__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) {
+  C_HANDLE_ERROR(*ptr_out = new kernel((cl_kernel)int_ptr_value, /* retain */ true);)
+    return 0;
+}
+
+void *context__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) {
+  C_HANDLE_ERROR(*ptr_out = new context((cl_context)int_ptr_value, /* retain */ true);)
+    return 0;
+}
+
+void *command_queue__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) {
+  C_HANDLE_ERROR(*ptr_out = new command_queue((cl_command_queue)int_ptr_value, /* retain */ true);)
+    return 0;
+}
+
+void *buffer__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) {
+  C_HANDLE_ERROR(*ptr_out = new buffer((cl_mem)int_ptr_value, /* retain */ true);)
+    return 0;
+}
+
+void *program__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) {
+  C_HANDLE_ERROR(*ptr_out = new program((cl_program)int_ptr_value, /* retain */ true);)
+    return 0;
+}
+
+void *event__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) {
+  C_HANDLE_ERROR(*ptr_out = new event((cl_event)int_ptr_value, /* retain */ true);)
+    return 0;
+}
+
   
 }
 
diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h
index fd68f5ea70e55a3e66beb0646e8bdcfe39591c8d..dad61b49716f58ceef1f92871171873b98b70048 100644
--- a/src/c_wrapper/wrap_cl_core.h
+++ b/src/c_wrapper/wrap_cl_core.h
@@ -62,6 +62,23 @@ error *_enqueue_read_buffer(void **ptr_event, void *ptr_command_queue, void *ptr
 error *memory_object_holder__get_info(void *ptr_memory_object_holder, cl_mem_info param, generic_info *out);
 long memory_object_holder__hash(void *ptr_memory_object_holder);
 void populate_constants(void(*add)(const char*, const char*, long value));
+
+intptr_t platform__int_ptr(void*);
+intptr_t kernel__int_ptr(void*);
+intptr_t context__int_ptr(void*);
+intptr_t command_queue__int_ptr(void*);
+intptr_t buffer__int_ptr(void*);
+intptr_t program__int_ptr(void*);
+intptr_t event__int_ptr(void*);
+
+void *platform__from_int_ptr(void **ptr_out, intptr_t int_ptr_value);
+void *kernel__from_int_ptr(void **ptr_out, intptr_t int_ptr_value);
+void *context__from_int_ptr(void **ptr_out, intptr_t int_ptr_value);
+void *command_queue__from_int_ptr(void **ptr_out, intptr_t int_ptr_value);
+void *buffer__from_int_ptr(void **ptr_out, intptr_t int_ptr_value);
+void *program__from_int_ptr(void **ptr_out, intptr_t int_ptr_value);
+void *event__from_int_ptr(void **ptr_out, intptr_t int_ptr_value);
+
 void _free(void*);
 void _free2(void**, uint32_t size);