public Object invoke(Object proxy, Method method, Object[] inArgs) throws Throwable { // Intercept Object methods if (OBJECT_TOSTRING.equals(method)) { return "Proxy interface to " + nativeLibrary; } else if (OBJECT_HASHCODE.equals(method)) { return new Integer(hashCode()); } else if (OBJECT_EQUALS.equals(method)) { Object o = inArgs[0]; if (o != null && Proxy.isProxyClass(o.getClass())) { return Function.valueOf(Proxy.getInvocationHandler(o) == this); } return Boolean.FALSE; } FunctionInfo f = null; synchronized (functions) { f = (FunctionInfo) functions.get(method); if (f == null) { f = new FunctionInfo(); f.isVarArgs = Function.isVarArgs(method); if (invocationMapper != null) { f.handler = invocationMapper.getInvocationHandler(nativeLibrary, method); } if (f.handler == null) { // Find the function to invoke String methodName = functionMapper.getFunctionName(nativeLibrary, method); if (methodName == null) { // Just in case the function mapper screwed up methodName = method.getName(); } f.function = nativeLibrary.getFunction(methodName, method); f.options = new HashMap(this.options); f.options.put(Function.OPTION_INVOKING_METHOD, method); } functions.put(method, f); } } if (f.isVarArgs) { inArgs = Function.concatenateVarArgs(inArgs); } if (f.handler != null) { return f.handler.invoke(proxy, method, inArgs); } return f.function.invoke(method.getReturnType(), inArgs, f.options); }