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); } }
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; }