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); } }
public int getPositionInVirtualTable( Pointer<Pointer<?>> pVirtualTable, Method method, NativeLibrary library) { // Pointer<?> typeInfo = pVirtualTable.get(1); int methodsOffset = 0; // library.isMSVC() ? 0 : -2;///2; String className = getCPPClassName(method.getDeclaringClass()); for (int iVirtual = 0; ; iVirtual++) { Pointer<?> pMethod = pVirtualTable.get(methodsOffset + iVirtual); String virtualMethodName = pMethod == null ? null : library.getSymbolName(pMethod.getPeer()); // System.out.println("#\n# At index " + methodsOffset + " + " + iVirtual + " of vptr for // class " + className + ", found symbol " + Long.toHexString(pMethod.getPeer()) + " = '" + // virtualMethodName + "'\n#"); if (virtualMethodName == null) { if (debug) info("\tVtable(" + className + ")[" + iVirtual + "] = null"); return -1; } try { MemberRef mr = library.parseSymbol(virtualMethodName); if (debug) info("\tVtable(" + className + ")[" + iVirtual + "] = " + virtualMethodName + " = " + mr); if (mr != null && mr.matchesSignature(method)) return iVirtual; else if (library.isMSVC() && !mr.matchesEnclosingType(method)) break; // no NULL terminator in MSVC++ vtables, so we have to guess when we've reached the // end } catch (Demangler.DemanglingException ex) { BridJ.warning( "Failed to demangle '" + virtualMethodName + "' during inspection of virtual table for '" + method.toGenericString() + "' : " + ex); } } return -1; }
public static void testSetGetIntBuffer(int n) { int[] expected = createExpectedInts(n); Pointer<Integer> p = Pointer.pointerToInts(expected); long peer = p.getPeer(); Iterator<Integer> it = p.iterator(); for (int i = 0; i < n; i++) { Integer obVal = it.next(); int val = obVal; if (val != expected[i]) throw new RuntimeException("at position i = " + i); } }
private String ptrToString(Pointer<?> ptr, NativeLibrary library) { return ptr == null ? "null" : Long.toHexString(ptr.getPeer()) + " (" + library.getSymbolName(ptr.getPeer()) + ")"; }