[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[cinvoke-svn] r76 - in trunk/cinvoke/bindings/java: . org/cinvoke
From: |
will |
Subject: |
[cinvoke-svn] r76 - in trunk/cinvoke/bindings/java: . org/cinvoke |
Date: |
7 Jul 2006 00:38:41 -0400 |
Author: will
Date: 2006-07-07 00:38:40 -0400 (Fri, 07 Jul 2006)
New Revision: 76
Modified:
trunk/cinvoke/bindings/java/Makefile
trunk/cinvoke/bindings/java/org/cinvoke/CInvProxy.java
trunk/cinvoke/bindings/java/org/cinvoke/CInvoke.java
trunk/cinvoke/bindings/java/org/cinvoke/CInvokeError.java
trunk/cinvoke/bindings/java/org/cinvoke/NativeInt.java
trunk/cinvoke/bindings/java/org/cinvoke/NativeLong.java
trunk/cinvoke/bindings/java/org/cinvoke/NativeLongLong.java
trunk/cinvoke/bindings/java/org/cinvoke/NativeShort.java
trunk/cinvoke/bindings/java/org/cinvoke/Natives.java
trunk/cinvoke/bindings/java/org/cinvoke/Ptr.java
Log:
finished up marshaling except for callbacks, added javadoc
Modified: trunk/cinvoke/bindings/java/Makefile
===================================================================
--- trunk/cinvoke/bindings/java/Makefile 2006-07-06 22:21:17 UTC (rev 75)
+++ trunk/cinvoke/bindings/java/Makefile 2006-07-07 04:38:40 UTC (rev 76)
@@ -23,3 +23,7 @@
test:
javac Test.java
LD_LIBRARY_PATH=. java Test
+
+doc:
+ rm -rf javadoc
+ javadoc -d javadoc org/cinvoke/*.java
Modified: trunk/cinvoke/bindings/java/org/cinvoke/CInvProxy.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/CInvProxy.java 2006-07-06
22:21:17 UTC (rev 75)
+++ trunk/cinvoke/bindings/java/org/cinvoke/CInvProxy.java 2006-07-07
04:38:40 UTC (rev 76)
@@ -1,267 +1,93 @@
package org.cinvoke;
import java.lang.reflect.*;
-import java.util.*;
class CInvProxy implements InvocationHandler {
- private long _ctx = 0;
private long _lib = 0;
private int _cc;
private int _encoding;
- private HashMap _functions;
- private HashMap _structs;
+ private Natives _n;
public CInvProxy(String libname, int cc, int encoding) {
- _ctx = Natives.createContext();
- if (_ctx == 0) throw new OutOfMemoryError();
- _lib = Natives.createLibrary(_ctx, libname);
+ _n = new Natives();
+ _lib = Natives.createLibrary(_n._ctx, libname);
if (_lib == 0) {
try {
- fail();
+ _n.fail();
} finally {
- Natives.deleteContext(_ctx);
- _ctx = 0;
+ _n.close();
}
}
_cc = cc;
_encoding = encoding;
- _functions = new HashMap();
- _structs = new HashMap();
}
protected void finalize() throws Throwable {
- close();
- }
-
- public void close() {
- for (Iterator i = _functions.values().iterator(); i.hasNext();)
- ((NativeMethod)i.next()).close();
- for (Iterator i = _structs.values().iterator(); i.hasNext();)
- ((NativeStruct)i.next()).close();
- if (_ctx != 0) {
- if (_lib != 0) {
- Natives.deleteLibrary(_ctx, _lib);
- _lib = 0;
- }
- Natives.deleteContext(_ctx);
- _ctx = 0;
+ if (_lib != 0) {
+ Natives.deleteLibrary(_n._ctx, _lib);
+ _lib = 0;
}
+ _n.close();
}
- private void fail() {
- throw new CInvokeError(Natives.getError(_ctx));
- }
-
- class NativeStruct {
- public NativeStruct(long ctx, long st) {
- _ctx = ctx;
- this.st = st;
- }
-
- public void close() {
- if (st != 0) {
- Natives.deleteStruct(_ctx, st);
- st = 0;
- }
- }
-
- public long st;
- private long _ctx;
- }
-
- class NativeMethod {
- public NativeMethod(long ctx, long func, long ep, int[] types,
- boolean hasret, int rettype) {
- this.func = func;
- this.ep = ep;
- this.types = types;
- this.hasret = hasret;
- this.rettype = rettype;
- _ctx = ctx;
- }
-
- public void close() {
- if (func != 0) {
- Natives.deleteFunction(_ctx, func);
- func = 0;
- }
- }
-
- private long _ctx;
- public long func;
- public long ep;
- public int[] types;
- public boolean hasret;
- public int rettype;
- }
-
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
- NativeMethod meth = (NativeMethod)_functions.get(method);
- if (meth == null) {
- meth = createNative(method);
- _functions.put(method, meth);
- }
- Class returncls = method.getReturnType();
- if (returncls.equals(Void.TYPE))
- returncls = null;
- Class realretcls = returncls;
- if (returncls.equals(String.class))
- realretcls = Ptr.class;
+ synchronized (_n) {
+ Natives.NativeMethod meth =
_n.createNativeMethod(method, _lib,
+ _cc);
+ Class returncls = method.getReturnType();
+ if (returncls.equals(Void.class))
+ returncls = null;
+ Class realretcls = returncls;
+ if (returncls.equals(String.class))
+ realretcls = Ptr.class;
- Class[] pclasses = method.getParameterTypes();
- Object[] params = marshalParams(method, pclasses, args);
- try {
- Object ret;
+ Class[] pclasses = method.getParameterTypes();
+ Object[] params = marshalParams(method, pclasses, args);
try {
- ret = Natives.invokeFunction(_ctx, meth.func,
meth.ep,
- params, meth.types, realretcls,
meth.rettype);
- } catch (Exception ex) {
- if (ex.getMessage().equals("invoke failed")) {
- fail();
- return null;
- } else
- throw ex;
- }
+ Object ret;
+ try {
+ ret = Natives.invokeFunction(_n._ctx,
meth.func, meth.ep,
+ params, meth.types, realretcls,
meth.rettype);
+ } catch (Exception ex) {
+ if (ex.getMessage().equals("invoke
failed")) {
+ _n.fail();
+ return null;
+ } else
+ throw ex;
+ }
- for (int i = 0; i < pclasses.length; i++) {
- if (pclasses[i].isArray()) {
-
unmarshalArray(((Ptr)params[i]).longValue(), args[i],
- pclasses[i].getComponentType());
+ for (int i = 0; i < pclasses.length; i++) {
+ if (pclasses[i].isArray()) {
+
_n.unmarshalArray(((Ptr)params[i]).longValue(), args[i],
+
pclasses[i].getComponentType());
+ }
}
- }
- if (returncls != null)
- return unmarshalReturnValue(ret, returncls);
- else
- return null;
- } finally {
- freeParams(method, params, args);
- }
- }
-
- private int gettypeint(Class cls, boolean thrw) {
- if (cls.isArray()) {
- if (cls.isInterface())
- throw new CInvokeError("Arrays of callbacks not
supported");
- if (cls.equals(String.class))
- throw new CInvokeError("Arrays of strings not
supported");
- return Natives.T_PTR;
- } else {
- if (cls.isInterface())
- return Natives.T_PTR;
- else if (cls.equals(String.class))
- return Natives.T_PTR;
- else if (cls.equals(Byte.class))
- return Natives.T_CHAR;
- else if (cls.equals(Short.class))
- return Natives.T_JSHORT;
- else if (cls.equals(Integer.class))
- return Natives.T_JINT;
- else if (cls.equals(Long.class))
- return Natives.T_JLONG;
- else if (cls.equals(Float.class))
- return Natives.T_FLOAT;
- else if (cls.equals(Double.class))
- return Natives.T_DOUBLE;
- else if (cls.equals(NativeShort.class))
- return Natives.T_SHORT;
- else if (cls.equals(NativeInt.class))
- return Natives.T_INT;
- else if (cls.equals(NativeLong.class))
- return Natives.T_LONG;
- else if (cls.equals(NativeLongLong.class))
- return Natives.T_EXTRALONG;
- else if (cls.equals(Ptr.class))
- return Natives.T_PTR;
- else {
- if (thrw)
- throw new CInvokeError(
- "Passing or returning structures by
value not supported");
+ if (returncls != null)
+ return unmarshalReturnValue(ret,
returncls);
else
- return STRUCT_TYPE;
+ return null;
+ } finally {
+ freeParams(method, params, args);
}
}
}
- private final static int STRUCT_TYPE = -999;
-
- private char gettypechar(int type) {
- switch (type) {
- case Natives.T_JSHORT:
- return '2';
- case Natives.T_JINT:
- return '4';
- case Natives.T_JLONG:
- return '8';
- case Natives.T_CHAR:
- return 'c';
- case Natives.T_SHORT:
- return 's';
- case Natives.T_INT:
- return 'i';
- case Natives.T_LONG:
- return 'l';
- case Natives.T_EXTRALONG:
- return 'e';
- case Natives.T_FLOAT:
- return 'f';
- case Natives.T_DOUBLE:
- return 'd';
- case Natives.T_PTR:
- return 'p';
- default:
- throw new UnknownError("unknown type");
- }
- }
-
- private NativeMethod createNative(Method method) {
- long ep = Natives.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.isArray())
- throw new CInvokeError("returning arrays not
supported");
- if (retcls.isInterface())
- throw new CInvokeError("returning callbacks not
supported");
- hasret = true;
- rettype = gettypeint(retcls, true);
- retfmt.append(gettypechar(rettype));
- }
-
- Class[] pclasses = method.getParameterTypes();
- int[] types = new int[pclasses.length];
- for (int i = 0; i < types.length; i++) {
- types[i] = gettypeint(pclasses[i], true);
- parmfmt.append(gettypechar(types[i]));
- }
-
- long func = Natives.createFunction(_ctx, _cc, retfmt.toString(),
- parmfmt.toString());
- if (func == 0)
- fail();
- return new NativeMethod(_ctx, func, ep, types, hasret, rettype);
- }
-
private Object[] marshalParams(Method method, Class[] pclasses,
Object[] rawparams) {
Object[] ret = new Object[rawparams.length];
for (int i = 0; i < ret.length; i++) {
if (pclasses[i].isArray())
- ret[i] =
marshalArray(pclasses[i].getComponentType(),
+ ret[i] =
_n.marshalArray(pclasses[i].getComponentType(),
rawparams[i]);
else if (pclasses[i].isInterface()) {
// XXX create callback
} else if (pclasses[i].equals(String.class))
- ret[i] = marshalString((String)rawparams[i]);
+ ret[i] = _n.marshalString((String)rawparams[i],
_encoding);
else
- ret[i] = marshalBasic(rawparams[i],
pclasses[i]);
+ ret[i] = _n.marshalBasic(rawparams[i],
pclasses[i]);
}
return ret;
@@ -280,247 +106,12 @@
}
}
- private Object unmarshalString(long p) {
- if (p == 0) return null;
- if (_encoding == CInvoke.ENC.UNICODE)
- return Natives.ptrToStringUnicode(p, -1);
- else
- return Natives.ptrToStringUTF8(p);
- }
-
private Object unmarshalReturnValue(Object ret, Class type) {
if (type.equals(String.class)) {
Ptr p = (Ptr)ret;
- return unmarshalString(p.longValue());
+ return _n.unmarshalString(p.longValue(), _encoding);
} else
return ret;
}
- private Object unmarshalStruct(long ptr, Class cls) {
- long st = getNativeStruct(cls).st;
- Field[] fields = cls.getFields();
- Object ret;
-
- try {
- ret = cls.newInstance();
- } catch (IllegalAccessException iae) {
- throw new CInvokeError("Cannot create new instance of
class " +
- cls.getName() + " due a security error: " +
iae.toString());
- } catch (InstantiationException ie) {
- throw new CInvokeError("Cannot create new instance of
class " +
- cls.getName() + " due to error: " +
ie.toString());
- }
- for (int i = 0; i < fields.length; i++) {
- Field fld = fields[i];
- Class tcls = fld.getType();
- Object val;
- int type = gettypeint(tcls, false);
- if (type == STRUCT_TYPE) {
- long p = Natives.getMemberPtrStruct(_ctx, st,
ptr,
- fld.getName());
- if (p == 0) fail();
- val = unmarshalStruct(p, tcls);
- } else {
- val = Natives.getMemberValueStruct(_ctx, st,
ptr,
- fld.getName(), tcls, type);
- }
- try {
- fld.set(ret, val);
- } catch (IllegalAccessException iae) {
- throw new CInvokeError(cls.getName() +
- " field access failed: " +
iae.toString());
- }
- }
-
- return ret;
- }
-
- private long marshalStruct(long outp, Object s, Class cls) {
- if (s == null)
- throw new CInvokeError("Invalid null value");
-
- long st = getNativeStruct(cls).st;
- Field[] fields = cls.getFields();
- for (int i = 0; i < fields.length; i++) {
- Field fld = fields[i];
- Class tcls = fld.getType();
- Object val;
- try {
- val = fld.get(s);
- } catch (IllegalAccessException iae) {
- throw new CInvokeError(cls.getName() +
- " field access failed: " +
iae.toString());
- }
- int type = gettypeint(tcls, false);
- if (type == STRUCT_TYPE) {
- long p = Natives.getMemberPtrStruct(_ctx, st,
- outp, fld.getName());
- if (p == 0) fail();
- marshalStruct(p, val, tcls);
- } else {
- if (Natives.setMemberValueStruct(_ctx, st, outp,
- fld.getName(), val, type) == 0)
- fail();
- }
- }
-
- int sz = Natives.sizeStruct(_ctx, st);
- if (sz == -1) fail();
- return outp + sz;
- }
-
- private Object marshalBasic(Object o, Class cls) {
- if (o == null) {
- if (cls.equals(Ptr.class))
- return new Ptr(0);
- else
- throw new CInvokeError("Invalid null value");
- } else
- return o;
- }
-
- private Ptr marshalString(String str) {
- if (str == null) return new Ptr(0);
-
- long l;
- if (_encoding == CInvoke.ENC.UNICODE)
- l = Natives.stringToPtrUnicode(str);
- else
- l = Natives.stringToPtrUTF8(str);
- if (l == 0)
- throw new OutOfMemoryError();
- return new Ptr(l);
- }
-
- private Ptr marshalArray(Class eltype, Object val) {
- if (val == null) return new Ptr(0);
-
- int numels = Array.getLength(val);
- int len = numels * sizeof(eltype);
-
- long ret = Natives.alloc(len);
- if (ret == 0)
- throw new OutOfMemoryError();
-
- int itype = gettypeint(eltype, false);
-
- long r = ret;
- for (int i = 0; i < numels; i++) {
- Object o = Array.get(val, i);
- if (itype == -909)
- r = marshalStruct(r, o, eltype);
- else
- r = Natives.writeValue(r, marshalBasic(o,
eltype), itype);
- }
-
- return new Ptr(ret);
- }
-
- private void unmarshalArray(long ptr, Object arr, Class eltype) {
- if (ptr == 0)
- throw new CInvokeError("Reading array from null
pointer");
- int numels = Array.getLength(arr);
-
- int itype = gettypeint(eltype, false);
- int elsize = sizeof(eltype);
-
- long p = ptr;
- for (int i = 0; i < numels; i++) {
- Object toset;
- if (itype == STRUCT_TYPE)
- toset = unmarshalStruct(p, eltype);
- else
- toset = Natives.readValue(p, eltype, itype);
- Array.set(arr, i, toset);
-
- p += elsize;
- }
- }
-
- private NativeStruct getNativeStruct(Class cls) {
- NativeStruct ret = (NativeStruct)_structs.get(cls);
-
- if (ret == null) {
- long st = Natives.createStruct(_ctx);
- if (st == 0)
- fail();
- Field[] fields = cls.getFields();
- for (int i = 0; i < fields.length; i++) {
- Class tcls = fields[i].getType();
- if (tcls.isArray()) {
- Natives.deleteStruct(_ctx, st);
- throw new CInvokeError(
- "Array structure members not
supported");
- }
- if (tcls.isInterface()) {
- Natives.deleteStruct(_ctx, st);
- throw new CInvokeError(
- "Callback structure members not
supported");
- }
- if (tcls.equals(String.class)) {
- Natives.deleteStruct(_ctx, st);
- throw new CInvokeError(
- "String structure members not
supported");
- }
- int type = gettypeint(tcls, false);
- if (type == STRUCT_TYPE) {
- if (Natives.addStructMemberStruct(_ctx,
st,
- fields[i].getName(),
- getNativeStruct(tcls).st) == 0)
{
- try { fail(); }
- finally {
Natives.deleteStruct(_ctx, st); }
- }
- } else {
- if (Natives.addValueMemberStruct(_ctx,
st,
- fields[i].getName(), type) ==
0) {
- try { fail(); }
- finally {
Natives.deleteStruct(_ctx, st); }
- }
- }
- }
- if (Natives.finishStruct(_ctx, st) == 0) {
- try { fail(); } finally {
Natives.deleteStruct(_ctx, st); }
- }
- ret = new NativeStruct(_ctx, st);
- _structs.put(cls, ret);
- }
-
- return ret;
- }
-
- public String ptrToString(Ptr ptr, int numchars) {
- if (_encoding == CInvoke.ENC.UNICODE)
- return Natives.ptrToStringUnicode(ptr.longValue(),
numchars);
- else
- return Natives.ptrToStringUTF8(ptr.longValue());
- }
- public Object[] ptrToArray(Ptr ptr, Class eltype, int num) {
- if (eltype.isInterface())
- throw new CInvokeError("Arrays of callbacks not
supported");
-
- Object ret = Array.newInstance(eltype, num);
-
- unmarshalArray(ptr.longValue(), ret, eltype);
-
- return (Object[])ret;
- }
- public int sizeof(Class type) {
- int itype = gettypeint(type, false);
- if (itype == STRUCT_TYPE) {
- int ret = Natives.sizeStruct(_ctx,
getNativeStruct(type).st);
- if (ret == -1)
- fail();
- return ret;
- } else
- return Natives.sizeofBasic(itype);
- }
- public int sizeof(Object obj) {
- Class cls = obj.getClass();
- if (cls.isArray()) {
- if (cls.isInterface())
- throw new CInvokeError("Arrays of callbacks not
supported");
- return Array.getLength(obj) *
sizeof(cls.getComponentType());
- } else
- return sizeof(cls);
- }
}
Modified: trunk/cinvoke/bindings/java/org/cinvoke/CInvoke.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/CInvoke.java 2006-07-06
22:21:17 UTC (rev 75)
+++ trunk/cinvoke/bindings/java/org/cinvoke/CInvoke.java 2006-07-07
04:38:40 UTC (rev 76)
@@ -1,27 +1,217 @@
package org.cinvoke;
import java.lang.reflect.*;
+/**
+ * Provides interfaces and related utility methods for calling C libraries.
+ * The CInvoke class is the main public class in the C/Invoke Java binding.
+ * In addition to the load() methods, which connect Java interfaces to native
+ * shared libraries, it contains methods which can marshal parameters or
+ * return values in situations where the library cannot determine the correct
+ * marshaling behavior on its own.
+ */
public final class CInvoke {
+ /**
+ * An enumeration of values representing different calling conventions.
+ */
public class CC {
+ /**
+ * The default calling convention on the current platform.
+ */
public static final int DEFAULT = -1;
+ /**
+ * The cdecl calling convention is the most common convention
on x86.
+ */
public static final int CDECL = 0;
+ /**
+ * The stdcall convention is used by the Microsoft Windows API.
+ */
public static final int STDCALL = 1;
+ /**
+ * The fastcall convention is rarely used under Microsoft
Windows.
+ */
public static final int FASTCALL = 2;
}
+ /**
+ * An enumeration which determines the encoding to use when marshalling
+ * strings.
+ */
public class ENC {
+ /**
+ * Marshal strings using the Java UTF-8 variant.
+ */
public static final int UTF8 = 0;
+ /**
+ * Marshal strings as two-byte Unicode values.
+ */
public static final int UNICODE = 1;
}
+ private static Natives _n;
+
+ static {
+ _n = new Natives();
+ }
+
+ /**
+ * Loads a native C library and attaches it to the given Java interface.
+ * See the documentation for the address@hidden #load(String, Class,
int, int)}
+ * overload for more information. Using this overload calls functions
+ * with the default calling convention and the UTF-8 string encoding.
+ * @param libname The platform-specific name of the library to load.
+ * @param iface The interface to attach to the library.
+ * @return An object instance which implements the given interface.
This
+ * object acts a proxy to the native C library.
+ */
public static Object load(String libname, Class iface) {
return load(libname, iface, CC.DEFAULT);
}
+ /**
+ * Loads a native C library and attaches it to the given Java interface.
+ * See the documentation for the address@hidden #load(String, Class,
int, int)}
+ * overload for more information. Using this overload calls functions
+ * with the UTF-8 string encoding.
+ * @param libname The platform-specific name of the library to load.
+ * @param iface The interface to attach to the library.
+ * @param callconv The calling convention to use on functions in this
+ * library, from the address@hidden CInvoke.CC} enumeration.
+ * @return An object instance which implements the given interface.
This
+ * object acts a proxy to the native C library.
+ */
public static Object load(String libname, Class iface, int callconv) {
return load(libname, iface, CC.DEFAULT, ENC.UTF8);
}
+ /**
+ * Loads a native C library and attaches it to the given Java interface.
+ * Each method in the given interface should correspond to a function
+ * symbol in the given library. However, individual symbols are not
+ * resolved until their corresponding methods are called for the first
time.
+ * The signature of the interface method determines how
+ * parameters and return values are marshaled to and from C. The
following
+ * types are allowed in method signatures:
+ * <li> <i>byte, Byte</i>: Marshaled as a C 'char' type.
+ * <li> <i>short, Short</i>: Marshaled as a 2-byte integer.
+ * <li> <i>int, Integer</i>: Marshaled as a 4-byte integer.
+ * <li> <i>long, Long</i>: Marshaled as an 8-byte integer.
+ * <li> <i>float, Float</i>: Marshaled as a C 'float' type.
+ * <li> <i>double, Double</i>: Marshaled as a C 'double' type.
+ * <li> <i>address@hidden NativeShort}</i>: Marshaled as a C 'short'
type.
+ * <li> <i>address@hidden NativeInt}</i>: Marshaled as a C 'int' type.
+ * <li> <i>address@hidden NativeLong}</i>: Marshaled as a C 'long' type.
+ * <li> <i>address@hidden NativeLongLong}</i>: Marshaled as a C 'long
long' type.
+ * <li> <i>address@hidden Ptr}</i>: Marshaled a C pointer value (i.e. a
void*, or
+ * any other pointer of the same size).
+ * <li> <i>String</i>: Marshaled as a constant string pointer, with
either
+ * UTF-8 or Unicode encoding. When used as a return value, marshaling
+ * 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
+ * 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
+ * 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
+ * cannot be used as return types.
+ * <li> <i>Any Array Type</i>: Arrays of any other valid type are
marshaled
+ * as pointers to C array values. Arrays, unlike Strings, are mutable;
+ * their elements are writable by unmanaged code, and after a C function
+ * returns, any value written to an array element is marshaled back to
+ * a corresponding Java value. This means you can use arrays whenever
+ * pointer or pass-by-reference semantics are required. However,
arrays of
+ * interfaces or Strings are not supported, and using an array as a
return
+ * type is not supported (use address@hidden ptrToString(Ptr, int, int)
ptrToString}
+ * or address@hidden ptrToArray(Ptr, Class, int) ptrToArray} instead).
+ * <li> <i>Any Class</i>: Class types other than those listed above are
+ * marshaled as C structures, with each public field of a class
+ * corresponding to a structure member. Structures cannot contain
members
+ * that are arrays, Strings, or interfaces. Members which have class
types
+ * are treated as embedded structure values. Structures can never be
+ * passed or returned by value, only inside arrays. To pass a pointer
to
+ * a structure to a function, pass an array with a length of 1. To
return
+ * a pointer to a function, return a Ptr value and convert it to an
array
+ * of structures with address@hidden ptrToArray(Ptr, Class, int)
ptrToArray}.
+ * @param libname The platform-specific name of the library to load.
+ * This is usually the name of a file containing the shared object file,
+ * i.e. mylib.dll or /lib/libmylib.so. The search path for library
files
+ * is also implementation and system-defined; specifying the full path
to
+ * a library file usually yields the most portable behavior.
+ * @param iface The interface to attach to the library. The returned
+ * object implements this interface.
+ * @param callconv The calling convention to use on functions in this
+ * library, from the address@hidden CInvoke.CC} enumeration.
+ * @param encoding The encoding to use when marshaling strings in and
out
+ * of this library, from the address@hidden CInvoke.ENC} enumeration.
+ * @return An object instance which implements the given interface.
This
+ * object acts a proxy to the native C library. When a method in the
given
+ * interface is called on this object, the name of the method is used as
+ * a symbol name to be looked up in the library. The parameters to the
+ * method are translated to their C equivalents, the C function is
called,
+ * and the return value (and any array values) are translated back to
+ * Java objects.
+ */
public static Object load(String libname, Class iface, int callconv,
int encoding) {
return Proxy.newProxyInstance(iface.getClassLoader(),
new Class[] { iface }, new CInvProxy(libname, callconv,
encoding));
}
+
+ /**
+ * Converts a pointer to an unmanaged buffer to a Java string value.
+ * @param ptr A pointer value which points to an array of bytes or
+ * Unicode characters.
+ * @param numchars The number of characters in the string. Specify a
+ * negative value
+ * to stop conversion at the first 0 character. This parameter is
ignored
+ * when using the UTF-8 encoding, which always stops at the first 0
byte.
+ * @param encoding The encoding to use, must be one of the values from
the
+ * address@hidden CInvoke.ENC} enumeration.
+ * @return The completed String value.
+ */
+ public static String ptrToString(Ptr ptr, int numchars, int encoding) {
+ synchronized (_n) {
+ return _n.ptrToString(ptr, numchars, encoding);
+ }
+ }
+ /**
+ * Converts a pointer to a native array to a Java array value.
+ * @param ptr A pointer value which points to a contiguous array of
+ * unmanaged values.
+ * @param eltype The type of the elements of the array to create. Must
+ * be either a class with public fields (marshalled as a C structure) or
+ * a "basic" type (Byte, Short, Int, Long, Float, Double, NativeShort,
+ * NativeInt, NativeLong, NativeLongLong, or Ptr).
+ * @param num The number of elements in the array.
+ * @return The completed Java array, cast to the Object[] type.
+ */
+ public static Object[] ptrToArray(Ptr ptr, Class eltype, int num) {
+ synchronized (_n) {
+ return _n.ptrToArray(ptr, eltype, num);
+ }
+ }
+ /**
+ * Utility method which returns the number of bytes required to hold an
+ * instance of the given marshalable type.
+ * @param type The type to retrieve the size of.
+ * @return The number of bytes of unmanaged memory required to hold an
+ * instance of the specified type.
+ */
+ public static int getSize(Class type) {
+ synchronized (_n) {
+ return _n.getSize(type);
+ }
+ }
+ /**
+ * Utility method which returns the number of bytes required
+ * to hold the given marshalable value. If the value is an array,
+ * the size returned will be the combined size of all array elements.
+ * @param obj The object to retrieve the size of.
+ * @return The number of bytes of unmanaged memory required to hold the
+ * object.
+ */
+ public static int getSize(Object obj) {
+ synchronized (_n) {
+ return _n.getSize(obj);
+ }
+ }
}
Modified: trunk/cinvoke/bindings/java/org/cinvoke/CInvokeError.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/CInvokeError.java 2006-07-06
22:21:17 UTC (rev 75)
+++ trunk/cinvoke/bindings/java/org/cinvoke/CInvokeError.java 2006-07-07
04:38:40 UTC (rev 76)
@@ -1,6 +1,13 @@
package org.cinvoke;
+/**
+ * Thrown when an error occurs in the C/Invoke Java binding.
+ */
public class CInvokeError extends Error {
+ /**
+ * Initializes a CInvokeError object.
+ * @param msg An error message.
+ */
public CInvokeError(String msg) {
super(msg);
}
Modified: trunk/cinvoke/bindings/java/org/cinvoke/NativeInt.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/NativeInt.java 2006-07-06
22:21:17 UTC (rev 75)
+++ trunk/cinvoke/bindings/java/org/cinvoke/NativeInt.java 2006-07-07
04:38:40 UTC (rev 76)
@@ -1,13 +1,42 @@
package org.cinvoke;
+import java.io.Serializable;
-public final class NativeInt {
+/**
+ * Used to send or read values of the C type 'int'. The size of integer values
+ * in C can vary with the current native platform. Declaring native interfaces
+ * with this type will always marshal the corresponding values as the correct
+ * size.
+ */
+public final class NativeInt implements Serializable {
+ /**
+ * Initializes a NativeInt instance.
+ * @param val The value to marshal. Note that not all the bits in the
long
+ * value are guaranteed to be used by the called platform.
+ */
public NativeInt(long val) {
_val = val;
}
+ /**
+ * Returns a marshaled value.
+ * @return The marshaled value. Note that not all the bits in the long
+ * value are guaranteed to be used by the called platform.
+ */
public long longVal() {
return _val;
}
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (this == o) return true;
+ if (!(NativeInt.class.isInstance(o))) return false;
+ NativeInt ni = (NativeInt)o;
+ return _val == ni._val;
+ }
+ public int hashCode() {
+ return new Long(_val).hashCode();
+ }
private long _val;
+
+ private static final long serialVersionUID = 1;
}
-
+
Modified: trunk/cinvoke/bindings/java/org/cinvoke/NativeLong.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/NativeLong.java 2006-07-06
22:21:17 UTC (rev 75)
+++ trunk/cinvoke/bindings/java/org/cinvoke/NativeLong.java 2006-07-07
04:38:40 UTC (rev 76)
@@ -1,13 +1,42 @@
package org.cinvoke;
+import java.io.Serializable;
-public final class NativeLong {
+/**
+ * Used to send or read values of the C type 'long'. The size of integer
values
+ * in C can vary with the current native platform. Declaring native interfaces
+ * with this type will always marshal the corresponding values as the correct
+ * size.
+ */
+public final class NativeLong implements Serializable {
+ /**
+ * Initializes a NativeLong instance.
+ * @param val The value to marshal. Note that not all the bits in the
long
+ * value are guaranteed to be used by the called platform.
+ */
public NativeLong(long val) {
_val = val;
}
+ /**
+ * Returns a marshaled value.
+ * @return The marshaled value. Note that not all the bits in the long
+ * value are guaranteed to be used by the called platform.
+ */
public long toLong() {
return _val;
}
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (this == o) return true;
+ if (!(NativeLong.class.isInstance(o))) return false;
+ NativeLong ni = (NativeLong)o;
+ return _val == ni._val;
+ }
+ public int hashCode() {
+ return new Long(_val).hashCode();
+ }
private long _val;
+
+ private static final long serialVersionUID = 1;
}
-
+
Modified: trunk/cinvoke/bindings/java/org/cinvoke/NativeLongLong.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/NativeLongLong.java 2006-07-06
22:21:17 UTC (rev 75)
+++ trunk/cinvoke/bindings/java/org/cinvoke/NativeLongLong.java 2006-07-07
04:38:40 UTC (rev 76)
@@ -1,13 +1,43 @@
package org.cinvoke;
+import java.io.Serializable;
-public final class NativeLongLong {
+/**
+ * Used to send or read values of the C type 'long long', if it is available.
+ * The size of integer values
+ * in C can vary with the current native platform. Declaring native interfaces
+ * with this type will always marshal the corresponding values as the correct
+ * size.
+ */
+public final class NativeLongLong implements Serializable {
+ /**
+ * Initializes a NativeLongLong instance.
+ * @param val The value to marshal. Note that not all the bits in the
long
+ * value are guaranteed to be used by the called platform.
+ */
public NativeLongLong(long val) {
_val = val;
}
+ /**
+ * Returns a marshaled value.
+ * @return The marshaled value. Note that not all the bits in the long
+ * value are guaranteed to be used by the called platform.
+ */
public long longValue() {
return _val;
}
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (this == o) return true;
+ if (!(NativeLongLong.class.isInstance(o))) return false;
+ NativeLongLong ni = (NativeLongLong)o;
+ return _val == ni._val;
+ }
+ public int hashCode() {
+ return new Long(_val).hashCode();
+ }
private long _val;
+
+ private static final long serialVersionUID = 1;
}
Modified: trunk/cinvoke/bindings/java/org/cinvoke/NativeShort.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/NativeShort.java 2006-07-06
22:21:17 UTC (rev 75)
+++ trunk/cinvoke/bindings/java/org/cinvoke/NativeShort.java 2006-07-07
04:38:40 UTC (rev 76)
@@ -1,13 +1,43 @@
package org.cinvoke;
+import java.io.Serializable;
-public final class NativeShort {
+/**
+ * Used to send or read values of the C type 'short'.
+ * The size of integer values
+ * in C can vary with the current native platform. Declaring native interfaces
+ * with this type will always marshal the corresponding values as the correct
+ * size.
+ */
+public final class NativeShort implements Serializable {
+ /**
+ * Initializes a NativeShort instance.
+ * @param val The value to marshal. Note that not all the bits in the
int
+ * value are guaranteed to be used by the called platform.
+ */
public NativeShort(int val) {
_val = val;
}
+ /**
+ * Returns a marshaled value.
+ * @return The marshaled value. Note that not all the bits in the int
+ * value are guaranteed to be used by the called platform.
+ */
public int intValue() {
return _val;
}
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (this == o) return true;
+ if (!(NativeShort.class.isInstance(o))) return false;
+ NativeShort ni = (NativeShort)o;
+ return _val == ni._val;
+ }
+ public int hashCode() {
+ return new Integer(_val).hashCode();
+ }
private int _val;
+
+ private static final long serialVersionUID = 1;
}
Modified: trunk/cinvoke/bindings/java/org/cinvoke/Natives.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/Natives.java 2006-07-06
22:21:17 UTC (rev 75)
+++ trunk/cinvoke/bindings/java/org/cinvoke/Natives.java 2006-07-07
04:38:40 UTC (rev 76)
@@ -1,4 +1,6 @@
package org.cinvoke;
+import java.util.*;
+import java.lang.reflect.*;
class Natives {
static {
@@ -46,15 +48,438 @@
public static native long stringToPtrUTF8(String str);
public static native long stringToPtrUnicode(String str);
- public static final int T_JSHORT = -1;
- public static final int T_JINT = -2;
- public static final int T_JLONG = -3;
- public static final int T_CHAR = 0;
- public static final int T_SHORT = 1;
- public static final int T_INT = 2;
- public static final int T_LONG = 3;
- public static final int T_EXTRALONG = 4;
- public static final int T_FLOAT = 5;
- public static final int T_DOUBLE = 6;
- public static final int T_PTR = 7;
+ private static final int T_JSHORT = -1;
+ private static final int T_JINT = -2;
+ private static final int T_JLONG = -3;
+ private static final int T_CHAR = 0;
+ private static final int T_SHORT = 1;
+ private static final int T_INT = 2;
+ private static final int T_LONG = 3;
+ private static final int T_EXTRALONG = 4;
+ private static final int T_FLOAT = 5;
+ private static final int T_DOUBLE = 6;
+ private static final int T_PTR = 7;
+
+ private final static int STRUCT_TYPE = -999;
+
+ public long _ctx = 0;
+ private HashMap _functions;
+ private HashMap _structs;
+
+ public Natives() {
+ _ctx = createContext();
+ if (_ctx == 0) throw new OutOfMemoryError();
+
+ _functions = new HashMap();
+ _structs = new HashMap();
+ }
+
+ public void close() {
+ for (Iterator i = _functions.values().iterator(); i.hasNext();)
+ ((NativeMethod)i.next()).close();
+ for (Iterator i = _structs.values().iterator(); i.hasNext();)
+ ((NativeStruct)i.next()).close();
+ if (_ctx != 0) {
+ deleteContext(_ctx);
+ _ctx = 0;
+ }
+ }
+
+ public void fail() {
+ throw new CInvokeError(getError(_ctx));
+ }
+
+ class NativeStruct {
+ public NativeStruct(long ctx, long st) {
+ _ctx = ctx;
+ this.st = st;
+ }
+
+ public void close() {
+ if (st != 0) {
+ deleteStruct(_ctx, st);
+ st = 0;
+ }
+ }
+
+ public long st;
+ private long _ctx;
+ }
+
+ class NativeMethod {
+ public NativeMethod(long ctx, long func, long ep, int[] types,
+ boolean hasret, int rettype) {
+ this.func = func;
+ this.ep = ep;
+ this.types = types;
+ this.hasret = hasret;
+ this.rettype = rettype;
+ _ctx = ctx;
+ }
+
+ public void close() {
+ if (func != 0) {
+ deleteFunction(_ctx, func);
+ func = 0;
+ }
+ }
+
+ private long _ctx;
+ public long func;
+ public long ep;
+ public int[] types;
+ public boolean hasret;
+ public int rettype;
+ }
+
+ public NativeMethod createNativeMethod(Method method, long lib, int cc)
{
+ NativeMethod meth = (NativeMethod)_functions.get(method);
+ if (meth == null) {
+ meth = createNative(method, lib, cc);
+ _functions.put(method, meth);
+ }
+ return meth;
+ }
+
+ private int gettypeint(Class cls, boolean thrw) {
+ if (cls.isArray()) {
+ if (cls.isInterface())
+ throw new CInvokeError("Arrays of callbacks not
supported");
+ if (cls.equals(String.class))
+ throw new CInvokeError("Arrays of strings not
supported");
+ return T_PTR;
+ } else {
+ if (cls.isInterface())
+ return T_PTR;
+ else if (cls.equals(String.class))
+ return T_PTR;
+ else if (cls.equals(Byte.class))
+ return T_CHAR;
+ else if (cls.equals(Short.class))
+ return T_JSHORT;
+ else if (cls.equals(Integer.class))
+ return T_JINT;
+ else if (cls.equals(Long.class))
+ return T_JLONG;
+ else if (cls.equals(Float.class))
+ return T_FLOAT;
+ else if (cls.equals(Double.class))
+ return T_DOUBLE;
+ else if (cls.equals(NativeShort.class))
+ return T_SHORT;
+ else if (cls.equals(NativeInt.class))
+ return T_INT;
+ else if (cls.equals(NativeLong.class))
+ return T_LONG;
+ else if (cls.equals(NativeLongLong.class))
+ return T_EXTRALONG;
+ else if (cls.equals(Ptr.class))
+ return T_PTR;
+ else {
+ if (thrw)
+ throw new CInvokeError(
+ "Passing or returning structures by
value not supported");
+ else
+ return STRUCT_TYPE;
+ }
+ }
+ }
+
+ private char gettypechar(int type) {
+ switch (type) {
+ case T_JSHORT:
+ return '2';
+ case T_JINT:
+ return '4';
+ case T_JLONG:
+ return '8';
+ case T_CHAR:
+ return 'c';
+ case T_SHORT:
+ return 's';
+ case T_INT:
+ return 'i';
+ case T_LONG:
+ return 'l';
+ case T_EXTRALONG:
+ return 'e';
+ case T_FLOAT:
+ return 'f';
+ case T_DOUBLE:
+ return 'd';
+ case T_PTR:
+ return 'p';
+ default:
+ throw new UnknownError("unknown type");
+ }
+ }
+
+ private NativeMethod createNative(Method method, long lib, int cc) {
+ long 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.isArray())
+ throw new CInvokeError("returning arrays not
supported");
+ if (retcls.isInterface())
+ throw new CInvokeError("returning callbacks not
supported");
+ hasret = true;
+ rettype = gettypeint(retcls, true);
+ retfmt.append(gettypechar(rettype));
+ }
+
+ Class[] pclasses = method.getParameterTypes();
+ int[] types = new int[pclasses.length];
+ for (int i = 0; i < types.length; i++) {
+ types[i] = gettypeint(pclasses[i], true);
+ parmfmt.append(gettypechar(types[i]));
+ }
+
+ long func = createFunction(_ctx, cc, retfmt.toString(),
+ parmfmt.toString());
+ if (func == 0)
+ fail();
+ return new NativeMethod(_ctx, func, ep, types, hasret, rettype);
+ }
+
+ public Object unmarshalString(long p, int encoding) {
+ if (p == 0) return null;
+ if (encoding == CInvoke.ENC.UNICODE)
+ return ptrToStringUnicode(p, -1);
+ else
+ return ptrToStringUTF8(p);
+ }
+
+ private Object unmarshalStruct(long ptr, Class cls) {
+ long st = getNativeStruct(cls).st;
+ Field[] fields = cls.getFields();
+ Object ret;
+
+ try {
+ ret = cls.newInstance();
+ } catch (IllegalAccessException iae) {
+ throw new CInvokeError("Cannot create new instance of
class " +
+ cls.getName() + " due a security error: " +
iae.toString());
+ } catch (InstantiationException ie) {
+ throw new CInvokeError("Cannot create new instance of
class " +
+ cls.getName() + " due to error: " +
ie.toString());
+ }
+ for (int i = 0; i < fields.length; i++) {
+ Field fld = fields[i];
+ Class tcls = fld.getType();
+ Object val;
+ int type = gettypeint(tcls, false);
+ if (type == STRUCT_TYPE) {
+ long p = getMemberPtrStruct(_ctx, st, ptr,
+ fld.getName());
+ if (p == 0) fail();
+ val = unmarshalStruct(p, tcls);
+ } else {
+ val = getMemberValueStruct(_ctx, st, ptr,
+ fld.getName(), tcls, type);
+ }
+ try {
+ fld.set(ret, val);
+ } catch (IllegalAccessException iae) {
+ throw new CInvokeError(cls.getName() +
+ " field access failed: " +
iae.toString());
+ }
+ }
+
+ return ret;
+ }
+
+ private long marshalStruct(long outp, Object s, Class cls) {
+ if (s == null)
+ throw new CInvokeError("Invalid null value");
+
+ long st = getNativeStruct(cls).st;
+ Field[] fields = cls.getFields();
+ for (int i = 0; i < fields.length; i++) {
+ Field fld = fields[i];
+ Class tcls = fld.getType();
+ Object val;
+ try {
+ val = fld.get(s);
+ } catch (IllegalAccessException iae) {
+ throw new CInvokeError(cls.getName() +
+ " field access failed: " +
iae.toString());
+ }
+ int type = gettypeint(tcls, false);
+ if (type == STRUCT_TYPE) {
+ long p = getMemberPtrStruct(_ctx, st,
+ outp, fld.getName());
+ if (p == 0) fail();
+ marshalStruct(p, val, tcls);
+ } else {
+ if (setMemberValueStruct(_ctx, st, outp,
+ fld.getName(), val, type) == 0)
+ fail();
+ }
+ }
+
+ int sz = sizeStruct(_ctx, st);
+ if (sz == -1) fail();
+ return outp + sz;
+ }
+
+ public Object marshalBasic(Object o, Class cls) {
+ if (o == null) {
+ if (cls.equals(Ptr.class))
+ return new Ptr(0);
+ else
+ throw new CInvokeError("Invalid null value");
+ } else
+ return o;
+ }
+
+ public Ptr marshalString(String str, int encoding) {
+ if (str == null) return new Ptr(0);
+
+ long l;
+ if (encoding == CInvoke.ENC.UNICODE)
+ l = stringToPtrUnicode(str);
+ else
+ l = stringToPtrUTF8(str);
+ if (l == 0)
+ throw new OutOfMemoryError();
+ return new Ptr(l);
+ }
+
+ public Ptr marshalArray(Class eltype, Object val) {
+ if (val == null) return new Ptr(0);
+
+ int numels = Array.getLength(val);
+ int len = numels * getSize(eltype);
+
+ long ret = alloc(len);
+ if (ret == 0)
+ throw new OutOfMemoryError();
+
+ int itype = gettypeint(eltype, false);
+
+ long r = ret;
+ for (int i = 0; i < numels; i++) {
+ Object o = Array.get(val, i);
+ if (itype == -909)
+ r = marshalStruct(r, o, eltype);
+ else
+ r = writeValue(r, marshalBasic(o, eltype),
itype);
+ }
+
+ return new Ptr(ret);
+ }
+
+ public void unmarshalArray(long ptr, Object arr, Class eltype) {
+ if (ptr == 0)
+ throw new CInvokeError("Reading array from null
pointer");
+ int numels = Array.getLength(arr);
+
+ int itype = gettypeint(eltype, false);
+ int elsize = getSize(eltype);
+
+ long p = ptr;
+ for (int i = 0; i < numels; i++) {
+ Object toset;
+ if (itype == STRUCT_TYPE)
+ toset = unmarshalStruct(p, eltype);
+ else
+ toset = readValue(p, eltype, itype);
+ Array.set(arr, i, toset);
+
+ p += elsize;
+ }
+ }
+
+ private NativeStruct getNativeStruct(Class cls) {
+ NativeStruct ret = (NativeStruct)_structs.get(cls);
+
+ if (ret == null) {
+ long st = createStruct(_ctx);
+ if (st == 0)
+ fail();
+ Field[] fields = cls.getFields();
+ for (int i = 0; i < fields.length; i++) {
+ Class tcls = fields[i].getType();
+ if (tcls.isArray()) {
+ deleteStruct(_ctx, st);
+ throw new CInvokeError(
+ "Array structure members not
supported");
+ }
+ if (tcls.isInterface()) {
+ deleteStruct(_ctx, st);
+ throw new CInvokeError(
+ "Callback structure members not
supported");
+ }
+ if (tcls.equals(String.class)) {
+ deleteStruct(_ctx, st);
+ throw new CInvokeError(
+ "String structure members not
supported");
+ }
+ int type = gettypeint(tcls, false);
+ if (type == STRUCT_TYPE) {
+ if (addStructMemberStruct(_ctx, st,
+ fields[i].getName(),
+ getNativeStruct(tcls).st) == 0)
{
+ try { fail(); }
+ finally { deleteStruct(_ctx,
st); }
+ }
+ } else {
+ if (addValueMemberStruct(_ctx, st,
+ fields[i].getName(), type) ==
0) {
+ try { fail(); }
+ finally { deleteStruct(_ctx,
st); }
+ }
+ }
+ }
+ if (finishStruct(_ctx, st) == 0) {
+ try { fail(); } finally { deleteStruct(_ctx,
st); }
+ }
+ ret = new NativeStruct(_ctx, st);
+ _structs.put(cls, ret);
+ }
+
+ return ret;
+ }
+
+ public String ptrToString(Ptr ptr, int numchars, int encoding) {
+ if (encoding == CInvoke.ENC.UNICODE)
+ return ptrToStringUnicode(ptr.longValue(), numchars);
+ else
+ return ptrToStringUTF8(ptr.longValue());
+ }
+ public Object[] ptrToArray(Ptr ptr, Class eltype, int num) {
+ if (eltype.isInterface())
+ throw new CInvokeError("Arrays of callbacks not
supported");
+
+ Object ret = Array.newInstance(eltype, num);
+
+ unmarshalArray(ptr.longValue(), ret, eltype);
+
+ return (Object[])ret;
+ }
+ public int getSize(Class type) {
+ int itype = gettypeint(type, false);
+ if (itype == STRUCT_TYPE) {
+ int ret = sizeStruct(_ctx, getNativeStruct(type).st);
+ if (ret == -1)
+ fail();
+ return ret;
+ } else
+ return sizeofBasic(itype);
+ }
+ public int getSize(Object obj) {
+ Class cls = obj.getClass();
+ if (cls.isArray()) {
+ if (cls.isInterface())
+ throw new CInvokeError("Arrays of callbacks not
supported");
+ return Array.getLength(obj) *
getSize(cls.getComponentType());
+ } else
+ return getSize(cls);
+ }
}
Modified: trunk/cinvoke/bindings/java/org/cinvoke/Ptr.java
===================================================================
--- trunk/cinvoke/bindings/java/org/cinvoke/Ptr.java 2006-07-06 22:21:17 UTC
(rev 75)
+++ trunk/cinvoke/bindings/java/org/cinvoke/Ptr.java 2006-07-07 04:38:40 UTC
(rev 76)
@@ -1,13 +1,51 @@
package org.cinvoke;
+import java.io.Serializable;
-public final class Ptr {
+/** Used to send or read values the size of a C pointer type. The size of
+ * pointer values in C can vary with the current native platform. Declaring
+ * native interfaces with this type will always marshal the corresponding
+ * values as the correct size.
+ */
+public final class Ptr implements Serializable {
+ /**
+ * Initializes a Ptr instance.
+ * @param val The value to marshal. Note that not all the bits in the
long
+ * value are guaranteed to be used by the called platform. Directly
using
+ * this constructor is discouraged. In particular, the C standard does
+ * not guarantee an integer representation for pointer values, so using
+ * this constructor may be undefined. The only integer value which is
+ * always defined is 0, which is equivalent to the NULL pointer.
Otherwise,
+ * you should only pass Ptr values to C functions which you have
received
+ * as return values from other C functions. */
public Ptr(long val) {
_val = val;
}
+ /**
+ * Returns a marshaled value.
+ * @return The marshaled value. Note that not all the bits in the long
+ * value are guaranteed to be used by the called platform. Use of this
+ * method is discouraged. In particular, the C standard does
+ * not guarantee an integer representation for pointer values, so using
+ * this method may be undefined. The only integer value which is
+ * always defined is 0, which is equivalent to the NULL pointer.
Otherwise,
+ * you should only pass Ptr values to C functions which you have received
+ * as return values from other C functions. */
public long longValue() {
return _val;
}
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (this == o) return true;
+ if (!(Ptr.class.isInstance(o))) return false;
+ Ptr ni = (Ptr)o;
+ return _val == ni._val;
+ }
+ public int hashCode() {
+ return new Long(_val).hashCode();
+ }
private long _val;
+
+ private static final long serialVersionUID = 1;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [cinvoke-svn] r76 - in trunk/cinvoke/bindings/java: . org/cinvoke,
will <=