[Top][All Lists]
[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);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [cinvoke-svn] r79 - trunk/cinvoke/bindings/java/org/cinvoke,
will <=