+(defmethod from-alien-form (location (class proxy-class) &rest args)
+ (declare (ignore args))
+ `(ensure-proxy-instance ',(class-name class) ,location))
+
+(defmethod from-alien-function ((class proxy-class) &rest args)
+ (declare (ignore args))
+ #'(lambda (location)
+ (ensure-proxy-instance class location)))
+
+(defmethod to-alien-form (instance (class proxy-class) &rest args)
+ (declare (ignore class args))
+ `(proxy-location ,instance))
+
+(defmethod to-alien-function ((class proxy-class) &rest args)
+ (declare (ignore class args))
+ #'proxy-location)
+
+(defmethod copy-from-alien-form (location (class proxy-class) &rest args)
+ (declare (ignore args))
+ (let ((class-name (class-name class)))
+ `(ensure-proxy-instance ',class-name
+ (reference-foreign ',class-name ,location))))
+
+(defmethod copy-from-alien-function ((class proxy-class) &rest args)
+ (declare (ignore args))
+ #'(lambda (location)
+ (ensure-proxy-instance class (reference-foreign class location))))
+
+(defmethod copy-to-alien-form (instance (class proxy-class) &rest args)
+ (declare (ignore args))
+ `(reference-foreign ',(class-name class) (proxy-location ,instance)))
+
+(defmethod copy-to-alien-function ((class proxy-class) &rest args)
+ (declare (ignore args))
+ #'(lambda (instance)
+ (reference-foreign class (proxy-location instance))))
+
+(defmethod writer-function ((class proxy-class) &rest args)
+ (declare (ignore args))
+ #'(lambda (instance location &optional (offset 0))
+ (assert (null-pointer-p (sap-ref-sap location offset)))
+ (setf
+ (sap-ref-sap location offset)
+ (reference-foreign class (proxy-location instance)))))
+
+(defmethod reader-function ((class proxy-class) &rest args)
+ (declare (ignore args))
+ #'(lambda (location &optional (offset 0))
+ (let ((instance (sap-ref-sap location offset)))
+ (unless (null-pointer-p instance)
+ (ensure-proxy-instance class (reference-foreign class instance))))))
+
+(defmethod destroy-function ((class proxy-class) &rest args)
+ (declare (ignore args))
+ #'(lambda (location &optional (offset 0))
+ (unreference-foreign class (sap-ref-sap location offset))))
+
+(defmethod unbound-value ((class proxy-class) &rest args)
+ (declare (ignore args))
+ (values t nil))
+
+(defgeneric ensure-proxy-instance (class location)
+ (:documentation "Returns a proxy object representing the foreign object at the give location."))
+
+(defmethod ensure-proxy-instance :around (class location)
+ (unless (null-pointer-p location)
+ (or
+ (find-cached-instance location)
+ (call-next-method))))
+
+(defmethod ensure-proxy-instance ((class symbol) location)
+ (ensure-proxy-instance (find-class class) location))