Пример #1
0
  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);
    }
  }
Пример #2
0
  DynamicFunction getConstructor(
      final Class<?> typeClass, final Type type, NativeLibrary lib, int constructorId) {
    Pair<Type, Integer> key = new Pair<Type, Integer>(type, constructorId);
    DynamicFunction constructor = constructors.get(key);
    if (constructor == null) {
      try {
        final Constructor<?> constr;
        try {
          constr = findConstructor(typeClass, constructorId, true);

          if (debug) BridJ.info("Found constructor for " + Utils.toString(type) + " : " + constr);
        } catch (NoSuchMethodException ex) {
          if (debug) BridJ.info("No constructor for " + Utils.toString(type));
          return null;
        }
        Symbol symbol =
            lib == null
                ? null
                : lib.getFirstMatchingSymbol(
                    new SymbolAccepter() {
                      public boolean accept(Symbol symbol) {
                        return symbol.matchesConstructor(
                            constr.getDeclaringClass() == Utils.getClass(type)
                                ? type
                                : constr.getDeclaringClass() /* TODO */,
                            constr);
                      }
                    });
        if (symbol == null) {
          if (debug)
            BridJ.info("No matching constructor for " + Utils.toString(type) + " (" + constr + ")");
          return null;
        }

        if (debug) info("Registering constructor " + constr + " as " + symbol.getName());

        // TODO do something with these args !
        int templateParametersCount = getTemplateParametersCount(typeClass);

        Class<?>[] consParamTypes = constr.getParameterTypes();
        Class<?>[] consThisParamTypes =
            new Class[consParamTypes.length + 1 - templateParametersCount];
        consThisParamTypes[0] = Pointer.class;
        System.arraycopy(
            consParamTypes,
            templateParametersCount,
            consThisParamTypes,
            1,
            consParamTypes.length - templateParametersCount);

        DynamicFunctionFactory constructorFactory =
            getDynamicFunctionFactory(lib, Style.ThisCall, void.class, consThisParamTypes);

        constructor = constructorFactory.newInstance(pointerToAddress(symbol.getAddress()));
        constructors.put(key, constructor);
      } catch (Throwable th) {
        th.printStackTrace();
        throw new RuntimeException(
            "Unable to create constructor " + constructorId + " for " + type + " : " + th, th);
      }
    }
    return constructor;
  }