protected <T extends CPPObject> Pointer<T> newCPPInstance(
      T instance, final Type type, int constructorId, Object... args) {
    Pointer<T> peer = null;
    try {
      final Class<T> typeClass = Utils.getClass(type);
      NativeLibrary lib = BridJ.getNativeLibrary(typeClass);

      if (BridJ.debug)
        info("Creating C++ instance of type " + type + " with args " + Arrays.asList(args));
      Pointer.Releaser releaser = newCPPReleaser(type, typeClass, lib);

      long size = sizeOf(type, null);
      peer = (Pointer) Pointer.allocateBytes(PointerIO.getInstance(type), size, releaser).as(type);

      DynamicFunction constructor =
          constructorId == SKIP_CONSTRUCTOR
              ? null
              : getConstructor(typeClass, type, lib, constructorId);

      if (lib != null && CPPObject.class.isAssignableFrom(typeClass)) {
        installRegularVTablePtr(type, lib, peer);
      } else {
        // TODO ObjCObject : call alloc on class type !!
      }

      // Setting the C++ template parameters in the instance :
      int templateParametersCount = getTemplateParametersCount(typeClass);
      if (templateParametersCount > 0) {
        Object[] templateArgs = new Object[templateParametersCount];
        System.arraycopy(args, 0, templateArgs, 0, templateParametersCount);
        setTemplateParameters(instance, typeClass, templateArgs);
      }

      // Calling the constructor with the non-template parameters :
      if (constructor != null) {
        Object[] consThisArgs = new Object[args.length - templateParametersCount + 1];
        consThisArgs[0] = peer;
        System.arraycopy(
            args, templateParametersCount, consThisArgs, 1, args.length - templateParametersCount);

        constructor.apply(consThisArgs);
      }

      // Install synthetic virtual table and associate the Java instance to the corresponding native
      // pointer :
      if (CPPObject.class.isAssignableFrom(typeClass)) {
        if (installSyntheticVTablePtr(type, lib, peer))
          BridJ.setJavaObjectFromNativePeer(peer.getPeer(), instance);
      } else {
        // TODO ObjCObject : call alloc on class type !!
      }
      return peer;
    } catch (Exception ex) {
      ex.printStackTrace();
      if (peer != null) {
        peer.release();
      }
      throw new RuntimeException("Failed to allocate new instance of type " + type, ex);
    }
  }
Exemple #2
0
 private void apply(org.bridj.Pointer<?> f, Object... args) {
   args = resolvePointers(args);
   Type[] classes = new Type[args.length];
   for (int i = 0; i < classes.length; i++) {
     classes[i] = args[i].getClass();
     if (args[i] instanceof String) {
       args[i] = Pointer.pointerToString(args[i].toString(), Pointer.StringType.C, null);
       classes[i] = Pointer.class;
     }
     if (args[i] instanceof Pointer) { // for all subclasses of Pointer
       classes[i] = Pointer.class;
     }
     // TODO is there a cleaner way (e.g. removing a layer, instead of adding one) ???
     if (args[i] instanceof Float) {
       classes[i] = float.class;
     }
     if (args[i] instanceof Double) {
       classes[i] = double.class;
     }
     if (args[i] instanceof Integer) {
       classes[i] = int.class;
     }
     if (args[i] instanceof Long) {
       classes[i] = long.class;
     }
     if (args[i] instanceof Boolean) {
       classes[i] = boolean.class;
     }
     // System.err.println("  ==  "+classes[i]+" => "+args[i].getClass()+" => "+args[i]);
   }
   final DynamicFunction<Object> asDynamicFunction =
       f.asDynamicFunction(null, Void.TYPE, classes);
   asDynamicFunction.apply(args);
 }
 public void cppDeleteArray(Pointer<?> ptr) {
   deleteArrayFct.apply(ptr);
 }
 public void cppDelete(Pointer<?> ptr) {
   deleteFct.apply(ptr);
 }