cinvoke-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cinvoke-svn] r79 - trunk/cinvoke/bindings/java/org/cinvoke


From: will
Subject: [cinvoke-svn] r79 - trunk/cinvoke/bindings/java/org/cinvoke
Date: 7 Jul 2006 15:36:23 -0400

Author: will
Date: 2006-07-07 15:36:23 -0400 (Fri, 07 Jul 2006)
New Revision: 79

Modified:
   trunk/cinvoke/bindings/java/org/cinvoke/CBThunk.java
   trunk/cinvoke/bindings/java/org/cinvoke/CInvProxy.java
   trunk/cinvoke/bindings/java/org/cinvoke/CInvoke.java
   trunk/cinvoke/bindings/java/org/cinvoke/Natives.java
Log:
callback implementation


Modified: trunk/cinvoke/bindings/java/org/cinvoke/CBThunk.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/CBThunk.java        2006-07-07 
15:40:10 UTC (rev 78)
+++ trunk/cinvoke/bindings/java/org/cinvoke/CBThunk.java        2006-07-07 
19:36:23 UTC (rev 79)
@@ -27,15 +27,21 @@
 */
 
 package org.cinvoke;
+import java.lang.reflect.*;
 
 class CBThunk {
-       public CBThunk() {
-               // XXX
+       public CBThunk(Object inst, Method meth) {
+               _inst = inst;
+               _method = meth;
        }
 
-       public Object cbfunc(Object[] params) {
-               // XXX
-               return null;
+       private Object _inst;
+       private Method _method;
+
+       public Object cbfunc(Object[] params)
+               throws IllegalAccessException,
+               IllegalArgumentException,
+               InvocationTargetException {
+               return _method.invoke(_method, params);
        }
 }
-

Modified: trunk/cinvoke/bindings/java/org/cinvoke/CInvProxy.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/CInvProxy.java      2006-07-07 
15:40:10 UTC (rev 78)
+++ trunk/cinvoke/bindings/java/org/cinvoke/CInvProxy.java      2006-07-07 
19:36:23 UTC (rev 79)
@@ -111,7 +111,7 @@
                                ret[i] = 
_n.marshalArray(pclasses[i].getComponentType(),
                                                rawparams[i]);
                        else if (pclasses[i].isInterface()) {
-                               // XXX create callback
+                               ret[i] = new Ptr(_n.createCB(rawparams[i], 
pclasses[i], _cc));
                        } else if (pclasses[i].equals(String.class))
                                ret[i] = _n.marshalString((String)rawparams[i], 
_encoding);
                        else
@@ -126,7 +126,7 @@
                Class[] pclasses = method.getParameterTypes();
                for (int i = 0; i < params.length; i++) {
                        if (pclasses[i].isInterface()) {
-                               // XXX delete callback
+                               _n.deleteCB(((Ptr)params[i]).longValue());
                        } else if (pclasses[i].isArray() ||
                                        pclasses[i].equals(String.class)) {
                                Natives.free(((Ptr)params[i]).longValue());

Modified: trunk/cinvoke/bindings/java/org/cinvoke/CInvoke.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/CInvoke.java        2006-07-07 
15:40:10 UTC (rev 78)
+++ trunk/cinvoke/bindings/java/org/cinvoke/CInvoke.java        2006-07-07 
19:36:23 UTC (rev 79)
@@ -133,10 +133,13 @@
         * continues up until the first 0 character.
         * <li> <i>Any Interface</i>: If an interface type is specified for a
         * parameter, then an instance of the interface will be marshaled as a
-        * function pointer.  The first method defined in the interface will be
+        * function pointer.  The interface specified should have one method
+        * defined.  This method will be
         * called back when unmanaged code calls the function pointer.  
Therefore,
         * the prototype of this method should match the callback protoype.
-        * Callbacks are currently only supported when all the calls to a
+        * Arrays and callbacks cannot be used as parameter types in callback
+        * prototypes, and Strings cannot be used as parameters or as the return
+        * type.  Callbacks are currently only supported when all the calls to a
         * callback are made from within the calling function.  Passing a 
managed
         * function pointer to a C function which stores the value and calls it
         * later in another thread may result in undefined behavior.  Interfaces

Modified: trunk/cinvoke/bindings/java/org/cinvoke/Natives.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/Natives.java        2006-07-07 
15:40:10 UTC (rev 78)
+++ trunk/cinvoke/bindings/java/org/cinvoke/Natives.java        2006-07-07 
19:36:23 UTC (rev 79)
@@ -93,6 +93,7 @@
        public long _ctx = 0;
        private HashMap _functions;
        private HashMap _structs;
+       private HashMap _callbacks;
 
        public Natives() {
                _ctx = createContext();
@@ -100,6 +101,7 @@
 
                _functions = new HashMap();
                _structs = new HashMap();
+               _callbacks = new HashMap();
        }
 
        public void close() {
@@ -243,19 +245,25 @@
        }
 
        private NativeMethod createNative(Method method, long lib, int cc) {
-               long ep = loadEPLibrary(_ctx, lib, method.getName());
-               if (ep == 0)
-                       fail();
+               long ep = 0;
+               if (lib != 0) {
+                       ep = loadEPLibrary(_ctx, lib, method.getName());
+                       if (ep == 0)
+                               fail();
+               }
                StringBuffer retfmt = new StringBuffer();
                StringBuffer parmfmt = new StringBuffer();
                boolean hasret = false;
                int rettype = 0;
                Class retcls = method.getReturnType();
-               if (!retcls.equals(Void.TYPE)) {
+               if (!retcls.equals(Void.class)) {
                        if (retcls.isArray())
                                throw new CInvokeError("returning arrays not 
supported");
                        if (retcls.isInterface())
                                throw new CInvokeError("returning callbacks not 
supported");
+                       if (lib == 0 && retcls.equals(String.class))
+                               throw new CInvokeError(
+                                       "returning strings not supported for 
callback methods");
                        hasret = true;
                        rettype = gettypeint(retcls, true);
                        retfmt.append(gettypechar(rettype));
@@ -264,6 +272,17 @@
                Class[] pclasses = method.getParameterTypes();
                int[] types = new int[pclasses.length];
                for (int i = 0; i < types.length; i++) {
+                       if (lib == 0) {
+                               if (pclasses[i].isArray())
+                                       throw new CInvokeError(
+                                               "passing arrays not supported 
for callbacks methods");
+                               if (pclasses[i].isInterface())
+                                       throw new CInvokeError(
+                                               "passing callbacks not 
supported for callback methods");
+                               if (pclasses[i].equals(String.class))
+                                       throw new CInvokeError(
+                                               "passing strings not supported 
for callback methods");
+                       }
                        types[i] = gettypeint(pclasses[i], true);
                        parmfmt.append(gettypechar(types[i]));
                }
@@ -484,6 +503,38 @@
                return ret;
        }
 
+       public long createCB(Object obj, Class iface, int cc) {
+               Method[] methods = iface.getDeclaredMethods();
+               if (methods.length != 1)
+                       throw new CInvokeError("Interface " + iface.getName() +
+                               " has " + methods.length + " methods, not 1");
+                               
+               Method method = methods[0];
+               NativeMethod meth = createNativeMethod(method, 0, cc);
+
+               long cb = createCallback(_ctx, meth.func, new CBThunk(obj, 
method),
+                               method.getParameterTypes(), meth.types, 
meth.hasret,
+                               meth.rettype);
+               if (cb == 0)
+                       fail();
+       
+               long ep = getEPCallback(_ctx, cb);
+               if (ep == 0) {
+                       try { fail(); }
+                       finally { deleteCallback(_ctx, cb); }
+               }
+
+               _callbacks.put(new Long(ep), new Long(cb));
+
+               return ep;
+       }
+
+       public void deleteCB(long ep) {
+               Long cb = (Long)_callbacks.get(new Long(ep));
+               if (cb != null)
+                       deleteCallback(_ctx, cb.longValue());
+       }
+
        public String ptrToString(Ptr ptr, int numchars, int encoding) {
                if (encoding == CInvoke.ENC.UNICODE)
                        return ptrToStringUnicode(ptr.longValue(), numchars);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]