Changes between Version 2 and Version 3 of UsingClassWriter


Ignore:
Timestamp:
12/01/10 22:48:51 (3 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 }}}