Dynamically Creating Java Interfaces
As of r13078, one can use the classwriter in the JVM package to dynamically create a Java interface.
An example of work in progress to use dynamically created Java interfaces for callbacks in JNA with CFFI:
(jvm::define-class-name +callback-object+ "com.sun.jna.Callback") (defconstant +dynamic-callback-package+ "org/armedbear/jna/dynamic/callbacks") #| TEST: (define-jinterface :int '(foo) '(:int)) |# (defun define-interface (rettype arg-names arg-types) "Returns the Java byte[] array of a class representing a Java interface." (declare (ignore rettype arg-names arg-types)) ;; XXX unimplemented (let* ((class-name-string (format nil "~A/~A" +dynamic-callback-package+ (symbol-name (gensym)))) (class-name (jvm::make-jvm-class-name class-name-string)) (class (jvm::make-class-interface-file class-name)) (method (jvm::make-jvm-method "callback" :int '(:int) :flags '(:public :abstract)))) (jvm::class-add-superinterface class +callback-object+) (jvm::class-add-method class method) (jvm::finalize-class-file class) (let ((s (sys::%make-byte-array-output-stream))) (jvm::write-class-file class s) (sys::%get-output-stream-bytes s)))) (defun load-class (class-bytes) "Load the Java byte[] array CLASS-BYTES as a Java class." (let ((load-class-method (jmethod "org.armedbear.lisp.JavaClassLoader" "loadClassFromByteArray" "[B"))) (jcall load-class-method java::*classloader* class-bytes))) (defun write-class (class-bytes pathname) "Write the Java byte[] array CLASS-BYTES to PATHNAME." (with-open-file (stream pathname :direction :output :element-type '(signed-byte 8)) (dotimes (i (jarray-length class-bytes)) (write-byte (jarray-ref class-bytes i) stream))))
Last modified 14 years ago
Last modified on 12/01/10 22:48:51