Changes between Version 2 and Version 3 of UsingClassWriter


Ignore:
Timestamp:
12/01/10 22:48:51 (4 years ago)
Author:
mevenson
Comment:

Updated to latest working code

Legend:

Unmodified
Added
Removed
Modified
  • UsingClassWriter

    v2 v3  
    11== Dynamically Creating Java Interfaces ==
    22
    3 As of r13071, one can use the classwriter in the JVM package to dynamically create a Java interface.
     3As of r13078, one can use the classwriter in the JVM package to dynamically create a Java interface.
    44
     5An example of work in progress to use dynamically created Java interfaces for callbacks in JNA with CFFI:
    56{{{
    6 (let* ((class-name (jvm::make-jvm-class-name "org/not/Foo"))
    7        (class (jvm::make-class-file class-name +java-object+ '(:public :interface)))
    8        (method (jvm::make-jvm-method "callback" :int '(:int) :flags
    9                                 '(:public :abstract))))
    10   (jvm::class-add-method class method)
    11   (jvm::finalize-class-file class)
    12   (with-open-file (s #p"Foo.class" :direction :output
    13                      :if-exists :supersede :element-type '(unsigned-byte 8))
    14     (jvm::write-class-file class s)))
     7(jvm::define-class-name +callback-object+ "com.sun.jna.Callback")
     8(defconstant +dynamic-callback-package+ "org/armedbear/jna/dynamic/callbacks")
     9
     10#|
     11TEST: (define-jinterface :int '(foo) '(:int))
     12|#
     13
     14(defun define-interface (rettype arg-names arg-types)
     15  "Returns the Java byte[] array of a class representing a Java interface."
     16  (declare (ignore rettype arg-names arg-types)) ;; XXX unimplemented
     17  (let* ((class-name-string (format nil "~A/~A"
     18                                    +dynamic-callback-package+ (symbol-name (gensym))))
     19         (class-name (jvm::make-jvm-class-name class-name-string))
     20         (class (jvm::make-class-interface-file class-name))
     21         (method (jvm::make-jvm-method "callback" :int '(:int)
     22                                       :flags '(:public :abstract))))
     23    (jvm::class-add-superinterface class +callback-object+)
     24    (jvm::class-add-method class method)
     25    (jvm::finalize-class-file class)
     26    (let ((s (sys::%make-byte-array-output-stream)))
     27      (jvm::write-class-file class s)
     28      (sys::%get-output-stream-bytes s))))
     29
     30(defun load-class (class-bytes)
     31  "Load the Java byte[] array CLASS-BYTES as a Java class."
     32  (let ((load-class-method
     33         (jmethod "org.armedbear.lisp.JavaClassLoader"
     34                  "loadClassFromByteArray" "[B")))
     35    (jcall load-class-method java::*classloader* class-bytes)))
     36
     37(defun write-class (class-bytes pathname)
     38  "Write the Java byte[] array CLASS-BYTES to PATHNAME."
     39  (with-open-file (stream pathname
     40                          :direction :output
     41                          :element-type '(signed-byte 8))
     42    (dotimes (i (jarray-length class-bytes))
     43      (write-byte (jarray-ref class-bytes i) stream))))
    1544 }}}