Beispiel #1
0
 private Object convertArgument(
     Object[] args,
     int index,
     Method invokingMethod,
     TypeMapper mapper,
     boolean allowObjects,
     Class expectedType) {
   Object arg = args[index];
   if (arg != null) {
     Class type = arg.getClass();
     ToNativeConverter converter = null;
     if (NativeMapped.class.isAssignableFrom(type)) {
       converter = NativeMappedConverter.getInstance(type);
     } else if (mapper != null) {
       converter = mapper.getToNativeConverter(type);
     }
     if (converter != null) {
       ToNativeContext context;
       if (invokingMethod != null) {
         context = new MethodParameterContext(this, args, index, invokingMethod);
       } else {
         context = new FunctionParameterContext(this, args, index);
       }
       arg = converter.toNative(arg, context);
     }
   }
   if (arg == null || isPrimitiveArray(arg.getClass())) {
     return arg;
   }
   Class argClass = arg.getClass();
   // Convert Structures to native pointers
   if (arg instanceof Structure) {
     Structure struct = (Structure) arg;
     struct.autoWrite();
     if (struct instanceof Structure.ByValue) {
       // Double-check against the method signature, if available
       Class ptype = struct.getClass();
       if (invokingMethod != null) {
         Class[] ptypes = invokingMethod.getParameterTypes();
         if (isVarArgs(invokingMethod)) {
           if (index < ptypes.length - 1) {
             ptype = ptypes[index];
           } else {
             Class etype = ptypes[ptypes.length - 1].getComponentType();
             if (etype != Object.class) {
               ptype = etype;
             }
           }
         } else {
           ptype = ptypes[index];
         }
       }
       if (Structure.ByValue.class.isAssignableFrom(ptype)) {
         return struct;
       }
     }
     return struct.getPointer();
   }
   // Convert Callback to Pointer
   else if (arg instanceof Callback) {
     return CallbackReference.getFunctionPointer((Callback) arg);
   }
   // String arguments are converted to native pointers here rather
   // than in native code so that the values will be valid until
   // this method returns.
   // Convert String to native pointer (const)
   else if (arg instanceof String) {
     return new NativeString((String) arg, false).getPointer();
   }
   // Convert WString to native pointer (const)
   else if (arg instanceof WString) {
     return new NativeString(arg.toString(), true).getPointer();
   }
   // Default conversion of boolean to int; if you want something
   // different, use a ToNativeConverter
   else if (arg instanceof Boolean) {
     return Boolean.TRUE.equals(arg) ? INTEGER_TRUE : INTEGER_FALSE;
   } else if (String[].class == argClass) {
     return new StringArray((String[]) arg, encoding);
   } else if (WString[].class == argClass) {
     return new StringArray((WString[]) arg);
   } else if (Pointer[].class == argClass) {
     return new PointerArray((Pointer[]) arg);
   } else if (NativeMapped[].class.isAssignableFrom(argClass)) {
     return new NativeMappedArray((NativeMapped[]) arg);
   } else if (Structure[].class.isAssignableFrom(argClass)) {
     // If the signature is Structure[], disallow
     // Structure.ByReference[] and Structure.ByReference elements
     Structure[] ss = (Structure[]) arg;
     Class type = argClass.getComponentType();
     boolean byRef = Structure.ByReference.class.isAssignableFrom(type);
     if (expectedType != null) {
       if (!Structure.ByReference[].class.isAssignableFrom(expectedType)) {
         if (byRef) {
           throw new IllegalArgumentException(
               "Function "
                   + getName()
                   + " declared Structure[] at parameter "
                   + index
                   + " but array of "
                   + type
                   + " was passed");
         }
         for (int i = 0; i < ss.length; i++) {
           if (ss[i] instanceof Structure.ByReference) {
             throw new IllegalArgumentException(
                 "Function "
                     + getName()
                     + " declared Structure[] at parameter "
                     + index
                     + " but element "
                     + i
                     + " is of Structure.ByReference type");
           }
         }
       }
     }
     if (byRef) {
       Structure.autoWrite(ss);
       Pointer[] pointers = new Pointer[ss.length + 1];
       for (int i = 0; i < ss.length; i++) {
         pointers[i] = ss[i] != null ? ss[i].getPointer() : null;
       }
       return new PointerArray(pointers);
     } else if (ss.length == 0) {
       throw new IllegalArgumentException("Structure array must have non-zero length");
     } else if (ss[0] == null) {
       Structure.newInstance(type).toArray(ss);
       return ss[0].getPointer();
     } else {
       Structure.autoWrite(ss);
       return ss[0].getPointer();
     }
   } else if (argClass.isArray()) {
     throw new IllegalArgumentException(
         "Unsupported array argument type: " + argClass.getComponentType());
   } else if (allowObjects) {
     return arg;
   } else if (!Native.isSupportedNativeType(arg.getClass())) {
     throw new IllegalArgumentException(
         "Unsupported argument type "
             + arg.getClass().getName()
             + " at parameter "
             + index
             + " of function "
             + getName());
   }
   return arg;
 }
Beispiel #2
0
 /** @see NativeLibrary#NativeLibrary(String,String,long,Map) implementation */
 Object invoke(Object[] args, Class returnType, boolean allowObjects) {
   Object result = null;
   if (returnType == null || returnType == void.class || returnType == Void.class) {
     Native.invokeVoid(peer, callFlags, args);
     result = null;
   } else if (returnType == boolean.class || returnType == Boolean.class) {
     result = valueOf(Native.invokeInt(peer, callFlags, args) != 0);
   } else if (returnType == byte.class || returnType == Byte.class) {
     result = new Byte((byte) Native.invokeInt(peer, callFlags, args));
   } else if (returnType == short.class || returnType == Short.class) {
     result = new Short((short) Native.invokeInt(peer, callFlags, args));
   } else if (returnType == char.class || returnType == Character.class) {
     result = new Character((char) Native.invokeInt(peer, callFlags, args));
   } else if (returnType == int.class || returnType == Integer.class) {
     result = new Integer(Native.invokeInt(peer, callFlags, args));
   } else if (returnType == long.class || returnType == Long.class) {
     result = new Long(Native.invokeLong(peer, callFlags, args));
   } else if (returnType == float.class || returnType == Float.class) {
     result = new Float(Native.invokeFloat(peer, callFlags, args));
   } else if (returnType == double.class || returnType == Double.class) {
     result = new Double(Native.invokeDouble(peer, callFlags, args));
   } else if (returnType == String.class) {
     result = invokeString(callFlags, args, false);
   } else if (returnType == WString.class) {
     String s = invokeString(callFlags, args, true);
     if (s != null) {
       result = new WString(s);
     }
   } else if (Pointer.class.isAssignableFrom(returnType)) {
     return invokePointer(callFlags, args);
   } else if (Structure.class.isAssignableFrom(returnType)) {
     if (Structure.ByValue.class.isAssignableFrom(returnType)) {
       Structure s =
           Native.invokeStructure(peer, callFlags, args, Structure.newInstance(returnType));
       s.autoRead();
       result = s;
     } else {
       result = invokePointer(callFlags, args);
       if (result != null) {
         Structure s = Structure.newInstance(returnType, (Pointer) result);
         s.conditionalAutoRead();
         result = s;
       }
     }
   } else if (Callback.class.isAssignableFrom(returnType)) {
     result = invokePointer(callFlags, args);
     if (result != null) {
       result = CallbackReference.getCallback(returnType, (Pointer) result);
     }
   } else if (returnType == String[].class) {
     Pointer p = invokePointer(callFlags, args);
     if (p != null) {
       result = p.getStringArray(0, encoding);
     }
   } else if (returnType == WString[].class) {
     Pointer p = invokePointer(callFlags, args);
     if (p != null) {
       String[] arr = p.getWideStringArray(0);
       WString[] warr = new WString[arr.length];
       for (int i = 0; i < arr.length; i++) {
         warr[i] = new WString(arr[i]);
       }
       result = warr;
     }
   } else if (returnType == Pointer[].class) {
     Pointer p = invokePointer(callFlags, args);
     if (p != null) {
       result = p.getPointerArray(0);
     }
   } else if (allowObjects) {
     result = Native.invokeObject(peer, callFlags, args);
     if (result != null && !returnType.isAssignableFrom(result.getClass())) {
       throw new ClassCastException(
           "Return type " + returnType + " does not match result " + result.getClass());
     }
   } else {
     throw new IllegalArgumentException(
         "Unsupported return type " + returnType + " in function " + getName());
   }
   return result;
 }