Search in sources :

Example 61 with Pointer

use of org.bytedeco.javacpp.Pointer in project javacpp by bytedeco.

the class Generator method call.

void call(MethodInformation methodInfo, String returnPrefix, boolean secondCall) {
    boolean needSecondCall = false;
    String indent = secondCall ? "" : methodInfo.throwsException != null ? "        " : "    ";
    String prefix = "(";
    String suffix = ")";
    int skipParameters = methodInfo.parameterTypes.length > 0 && methodInfo.parameterTypes[0] == Class.class ? 1 : 0;
    Index index = methodInfo.method.getAnnotation(Index.class);
    if (index == null && methodInfo.pairedMethod != null) {
        index = methodInfo.pairedMethod.getAnnotation(Index.class);
    }
    if (methodInfo.deallocator) {
        out.println(indent + "void* allocatedAddress = jlong_to_ptr(arg0);");
        out.println(indent + "void (*deallocatorAddress)(void*) = (void(*)(void*))jlong_to_ptr(arg1);");
        out.println(indent + "if (deallocatorAddress != NULL && allocatedAddress != NULL) {");
        out.println(indent + "    (*deallocatorAddress)(allocatedAddress);");
        out.println(indent + "}");
        // nothing else should be appended here for deallocator
        return;
    } else if (!FunctionPointer.class.isAssignableFrom(methodInfo.cls) && (methodInfo.valueGetter || methodInfo.valueSetter || methodInfo.memberGetter || methodInfo.memberSetter)) {
        boolean wantsPointer = false;
        int k = methodInfo.parameterTypes.length - 1;
        if ((methodInfo.valueSetter || methodInfo.memberSetter) && !(by(methodInfo, k) instanceof ByRef) && adapterInformation(false, methodInfo, k) == null && methodInfo.parameterTypes[k] == String.class) {
            // special considerations for char arrays as strings
            out.print(indent + "strcpy((char*)");
            wantsPointer = true;
            prefix = ", ";
        } else if (k >= 1 && methodInfo.parameterTypes[0].isArray() && methodInfo.parameterTypes[0].getComponentType().isPrimitive() && (methodInfo.parameterTypes[1] == int.class || methodInfo.parameterTypes[1] == long.class)) {
            // special considerations for primitive arrays
            out.print(indent + "memcpy(");
            wantsPointer = true;
            prefix = ", ";
            if (methodInfo.memberGetter || methodInfo.valueGetter) {
                out.print("ptr0 + arg1, ");
            } else {
                // methodInfo.memberSetter || methodInfo.valueSetter
                prefix += "ptr0 + arg1, ";
            }
            skipParameters = 2;
            suffix = " * sizeof(*ptr0)" + suffix;
        } else {
            out.print(indent + returnPrefix);
            prefix = methodInfo.valueGetter || methodInfo.memberGetter ? "" : " = ";
            suffix = "";
        }
        if (Modifier.isStatic(methodInfo.modifiers) || !Pointer.class.isAssignableFrom(methodInfo.cls)) {
            out.print(cppScopeName(methodInfo));
        } else if (methodInfo.memberGetter || methodInfo.memberSetter) {
            if (index != null) {
                out.print("(*ptr)");
                prefix = "." + methodInfo.memberName[0] + prefix;
            } else {
                out.print("ptr->" + methodInfo.memberName[0]);
            }
        } else {
            // methodInfo.valueGetter || methodInfo.valueSetter
            String cast = cast(methodInfo.returnType, methodInfo.annotations);
            if (index == null && cast.length() > 0) {
                // make sure to cast the returned pointer and not the value
                out.print("*(" + cast.substring(1, cast.length() - 1) + "*)&");
            }
            out.print(index != null ? "(*ptr)" : methodInfo.dim > 0 || wantsPointer ? "ptr" : "*ptr");
        }
    } else if (methodInfo.bufferGetter) {
        out.print(indent + returnPrefix + "ptr");
        prefix = "";
        suffix = "";
    } else {
        // function call
        out.print(indent + returnPrefix);
        if (FunctionPointer.class.isAssignableFrom(methodInfo.cls)) {
            if (methodInfo.cls.isAnnotationPresent(Namespace.class)) {
                out.print("(ptr0->*(ptr->ptr))");
                skipParameters = 1;
                if (methodInfo.valueGetter || methodInfo.valueSetter) {
                    // this is get/put for a field pointer, not a real function
                    prefix = methodInfo.valueGetter ? "" : " = ";
                    suffix = "";
                }
            } else {
                if (methodInfo.valueGetter || methodInfo.valueSetter) {
                    out.print("ptr->ptr");
                    prefix = methodInfo.valueGetter ? "" : " = ";
                    suffix = "";
                } else {
                    out.print("(*ptr->ptr)");
                }
            }
        } else if (methodInfo.allocator) {
            String[] typeName = cppTypeName(methodInfo.cls);
            String valueTypeName = valueTypeName(typeName);
            if (virtualFunctions.containsKey(methodInfo.cls)) {
                String subType = "JavaCPP_" + mangle(valueTypeName);
                valueTypeName = subType;
            }
            if (methodInfo.cls == Pointer.class) {
                // can't allocate a "void", so simply assign the argument instead
                prefix = "";
                suffix = "";
            } else {
                out.print((noException(methodInfo.cls, methodInfo.method) ? "new (std::nothrow) " : "new ") + valueTypeName + typeName[1]);
                if (methodInfo.arrayAllocator) {
                    prefix = "[";
                    suffix = "]";
                }
            }
        } else if (Modifier.isStatic(methodInfo.modifiers) || !Pointer.class.isAssignableFrom(methodInfo.cls)) {
            out.print(cppScopeName(methodInfo));
        } else {
            String name = methodInfo.memberName[0];
            String[] typeName = cppTypeName(methodInfo.cls);
            String valueTypeName = valueTypeName(typeName);
            if (virtualFunctions.containsKey(methodInfo.cls) && !secondCall) {
                String subType = "JavaCPP_" + mangle(valueTypeName);
                if (Modifier.isPublic(methodInfo.method.getModifiers())) {
                    // non-protected method that could be from any subclass, so check for ours
                    out.print("(dynamic_cast<" + subType + "*>(ptr) != NULL ? ");
                    needSecondCall = true;
                }
                if (methodInfo.method.isAnnotationPresent(Virtual.class)) {
                    name = "super_" + name;
                }
                out.print("((" + subType + "*)ptr)->" + name);
            } else if (index != null) {
                out.print("(*ptr)");
                prefix = "." + name + prefix;
            } else {
                String op = name.startsWith("operator") ? name.substring(8).trim() : "";
                if (methodInfo.parameterTypes.length > 0 && (op.equals("=") || op.equals("+") || op.equals("-") || op.equals("*") || op.equals("/") || op.equals("%") || op.equals("==") || op.equals("!=") || op.equals("<") || op.equals(">") || op.equals("<=") || op.equals(">="))) {
                    out.print("((*ptr)");
                    prefix = op + prefix;
                    suffix += ")";
                } else {
                    out.print("ptr->" + name);
                }
            }
        }
    }
    for (int j = skipParameters; j <= methodInfo.parameterTypes.length; j++) {
        if (j == skipParameters + methodInfo.dim) {
            if (methodInfo.memberName.length > 1) {
                out.print(methodInfo.memberName[1]);
            }
            out.print(prefix);
            if (methodInfo.withEnv) {
                out.print(Modifier.isStatic(methodInfo.modifiers) ? "env, cls" : "env, obj");
                if (methodInfo.parameterTypes.length - skipParameters - methodInfo.dim > 0) {
                    out.print(", ");
                }
            }
        }
        if (j == methodInfo.parameterTypes.length) {
            break;
        }
        if (j < skipParameters + methodInfo.dim) {
            // the C++ operator does with them when the Index annotation is present
            if (index == null || index.function().length() == 0) {
                out.print("[");
            } else {
                out.print("." + index.function() + "(");
            }
        }
        Annotation passBy = by(methodInfo, j);
        String cast = cast(methodInfo, j);
        AdapterInformation adapterInfo = methodInfo.parameterRaw[j] ? null : adapterInformation(false, methodInfo, j);
        if (FunctionPointer.class.isAssignableFrom(methodInfo.cls) && !methodInfo.cls.isAnnotationPresent(Namespace.class) && methodInfo.valueSetter) {
            String[] typeName = cppTypeName(methodInfo.cls);
            cast = "(" + typeName[0] + typeName[1] + ")";
        }
        if (Enum.class.isAssignableFrom(methodInfo.parameterTypes[j])) {
            accessesEnums = true;
            out.print(cast + "val" + j);
        } else if (("(void*)".equals(cast) || "(void *)".equals(cast)) && methodInfo.parameterTypes[j] == long.class) {
            out.print("jlong_to_ptr(arg" + j + ")");
        } else if (methodInfo.parameterTypes[j].isPrimitive()) {
            out.print(cast + "arg" + j);
        } else if (adapterInfo != null) {
            cast = adapterInfo.cast.trim();
            if (cast.length() > 0 && !cast.startsWith("(") && !cast.endsWith(")")) {
                cast = "(" + cast + ")";
            }
            String cast2 = adapterInfo.cast2.trim();
            if (cast2.length() > 0 && !cast2.startsWith("(") && !cast2.endsWith(")")) {
                cast2 = "(" + cast2 + ")";
            }
            out.print(cast + cast2 + "adapter" + j);
            j += adapterInfo.argc - 1;
        } else if (FunctionPointer.class.isAssignableFrom(methodInfo.parameterTypes[j]) && !(passBy instanceof ByVal || passBy instanceof ByRef)) {
            if (passBy instanceof ByPtrRef) {
                out.print(cast + "(ptr" + j + "->ptr)");
            } else {
                out.print(cast + "(ptr" + j + " == NULL ? NULL : " + (passBy instanceof ByPtrPtr ? "&ptr" : "ptr") + j + "->ptr)");
            }
        } else if (passBy instanceof ByVal || (passBy instanceof ByRef && methodInfo.parameterTypes[j] != String.class)) {
            String nullValue = passBy instanceof ByVal ? ((ByVal) passBy).nullValue() : passBy instanceof ByRef ? ((ByRef) passBy).nullValue() : "";
            out.print((nullValue.length() > 0 ? "ptr" + j + " == NULL ? " + nullValue + " : " : "") + "*" + cast + "ptr" + j);
        } else if (passBy instanceof ByPtrPtr) {
            out.print(cast + "(arg" + j + " == NULL ? NULL : &ptr" + j + ")");
        } else {
            // ByPtr || ByPtrRef || (ByRef && std::string)
            out.print(cast + "ptr" + j);
        }
        if (j < skipParameters + methodInfo.dim) {
            if (index == null || index.function().length() == 0) {
                out.print("]");
            } else {
                out.print(")");
            }
        } else if (j < methodInfo.parameterTypes.length - 1) {
            out.print(", ");
        }
    }
    out.print(suffix);
    if (methodInfo.memberName.length > 2) {
        out.print(methodInfo.memberName[2]);
    }
    if (by(methodInfo.annotations) instanceof ByRef && methodInfo.returnType == String.class) {
        // special considerations for std::string
        out.print(");\n" + indent + "rptr = rstr.c_str()");
    }
    if (needSecondCall) {
        call(methodInfo, " : ", true);
        out.print(")");
    }
}
Also used : FunctionPointer(org.bytedeco.javacpp.FunctionPointer) ByRef(org.bytedeco.javacpp.annotation.ByRef) ByPtrRef(org.bytedeco.javacpp.annotation.ByPtrRef) Index(org.bytedeco.javacpp.annotation.Index) CLongPointer(org.bytedeco.javacpp.CLongPointer) CharPointer(org.bytedeco.javacpp.CharPointer) IntPointer(org.bytedeco.javacpp.IntPointer) BytePointer(org.bytedeco.javacpp.BytePointer) PointerPointer(org.bytedeco.javacpp.PointerPointer) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) LongPointer(org.bytedeco.javacpp.LongPointer) ShortPointer(org.bytedeco.javacpp.ShortPointer) BoolPointer(org.bytedeco.javacpp.BoolPointer) DoublePointer(org.bytedeco.javacpp.DoublePointer) FloatPointer(org.bytedeco.javacpp.FloatPointer) Pointer(org.bytedeco.javacpp.Pointer) SizeTPointer(org.bytedeco.javacpp.SizeTPointer) ByPtrPtr(org.bytedeco.javacpp.annotation.ByPtrPtr) Annotation(java.lang.annotation.Annotation) Namespace(org.bytedeco.javacpp.annotation.Namespace) ByVal(org.bytedeco.javacpp.annotation.ByVal)

Example 62 with Pointer

use of org.bytedeco.javacpp.Pointer in project javacpp by bytedeco.

the class Generator method classes.

boolean classes(boolean handleExceptions, boolean defineAdapters, boolean convertStrings, boolean declareEnums, String loadSuffix, String baseLoadSuffix, String classPath, Class<?>... classes) {
    String version = Generator.class.getPackage().getImplementationVersion();
    if (version == null) {
        version = "unknown";
    }
    String warning = "// Generated by JavaCPP version " + version + ": DO NOT EDIT THIS FILE";
    out.println(warning);
    out.println();
    if (out2 != null) {
        out2.println(warning);
        out2.println();
    }
    ClassProperties clsProperties = Loader.loadProperties(classes, properties, true);
    for (String s : clsProperties.get("platform.pragma")) {
        out.println("#pragma " + s);
    }
    for (String s : clsProperties.get("platform.define")) {
        out.println("#define " + s);
    }
    out.println();
    out.println("#ifdef _WIN32");
    out.println("    #define _JAVASOFT_JNI_MD_H_");
    out.println();
    out.println("    #define JNIEXPORT __declspec(dllexport)");
    out.println("    #define JNIIMPORT __declspec(dllimport)");
    out.println("    #define JNICALL __stdcall");
    out.println();
    out.println("    typedef int jint;");
    out.println("    typedef long long jlong;");
    out.println("    typedef signed char jbyte;");
    out.println("#elif defined(__GNUC__) && !defined(__ANDROID__)");
    out.println("    #define _JAVASOFT_JNI_MD_H_");
    out.println();
    out.println("    #define JNIEXPORT __attribute__((visibility(\"default\")))");
    out.println("    #define JNIIMPORT");
    out.println("    #define JNICALL");
    out.println();
    out.println("    typedef int jint;");
    out.println("    typedef long long jlong;");
    out.println("    typedef signed char jbyte;");
    out.println("#endif");
    out.println();
    out.println("#include <jni.h>");
    if (out2 != null) {
        out2.println("#include <jni.h>");
    }
    out.println();
    out.println("#ifdef __ANDROID__");
    out.println("    #include <android/log.h>");
    out.println("#elif defined(__APPLE__) && defined(__OBJC__)");
    out.println("    #include <TargetConditionals.h>");
    out.println("    #include <Foundation/Foundation.h>");
    out.println("#endif");
    out.println();
    out.println("#ifdef __linux__");
    out.println("    #include <malloc.h>");
    out.println("    #include <sys/types.h>");
    out.println("    #include <sys/stat.h>");
    out.println("    #include <sys/sysinfo.h>");
    out.println("    #include <fcntl.h>");
    out.println("    #include <unistd.h>");
    out.println("    #include <dlfcn.h>");
    out.println("    #include <link.h>");
    out.println("#elif defined(__APPLE__)");
    out.println("    #include <sys/types.h>");
    out.println("    #include <sys/sysctl.h>");
    out.println("    #include <mach/mach_init.h>");
    out.println("    #include <mach/mach_host.h>");
    out.println("    #include <mach/task.h>");
    out.println("    #include <unistd.h>");
    out.println("    #include <dlfcn.h>");
    out.println("    #include <mach-o/dyld.h>");
    out.println("#elif defined(_WIN32)");
    out.println("    #define NOMINMAX");
    out.println("    #include <windows.h>");
    out.println("    #include <psapi.h>");
    out.println("#endif");
    out.println();
    out.println("#if defined(__ANDROID__) || TARGET_OS_IPHONE");
    out.println("    #define NewWeakGlobalRef(obj) NewGlobalRef(obj)");
    out.println("    #define DeleteWeakGlobalRef(obj) DeleteGlobalRef(obj)");
    out.println("#endif");
    out.println();
    out.println("#include <limits.h>");
    out.println("#include <stddef.h>");
    out.println("#ifndef _WIN32");
    out.println("    #include <stdint.h>");
    out.println("#endif");
    out.println("#include <stdio.h>");
    out.println("#include <stdlib.h>");
    out.println("#include <string.h>");
    out.println("#include <exception>");
    out.println("#include <memory>");
    out.println("#include <new>");
    if (baseLoadSuffix == null || baseLoadSuffix.isEmpty()) {
        out.println();
        out.println("#if defined(NATIVE_ALLOCATOR) && defined(NATIVE_DEALLOCATOR)");
        out.println("    void* operator new(std::size_t size, const std::nothrow_t&) throw() {");
        out.println("        return NATIVE_ALLOCATOR(size);");
        out.println("    }");
        out.println("    void* operator new[](std::size_t size, const std::nothrow_t&) throw() {");
        out.println("        return NATIVE_ALLOCATOR(size);");
        out.println("    }");
        out.println("    void* operator new(std::size_t size) throw(std::bad_alloc) {");
        out.println("        return NATIVE_ALLOCATOR(size);");
        out.println("    }");
        out.println("    void* operator new[](std::size_t size) throw(std::bad_alloc) {");
        out.println("        return NATIVE_ALLOCATOR(size);");
        out.println("    }");
        out.println("    void operator delete(void* ptr) throw() {");
        out.println("        NATIVE_DEALLOCATOR(ptr);");
        out.println("    }");
        out.println("    void operator delete[](void* ptr) throw() {");
        out.println("        NATIVE_DEALLOCATOR(ptr);");
        out.println("    }");
        out.println("#endif");
    }
    out.println();
    out.println("#define jlong_to_ptr(a) ((void*)(uintptr_t)(a))");
    out.println("#define ptr_to_jlong(a) ((jlong)(uintptr_t)(a))");
    out.println();
    out.println("#if defined(_MSC_VER)");
    out.println("    #define JavaCPP_noinline __declspec(noinline)");
    out.println("    #define JavaCPP_hidden /* hidden by default */");
    out.println("#elif defined(__GNUC__)");
    out.println("    #define JavaCPP_noinline __attribute__((noinline)) __attribute__ ((unused))");
    out.println("    #define JavaCPP_hidden   __attribute__((visibility(\"hidden\"))) __attribute__ ((unused))");
    out.println("#else");
    out.println("    #define JavaCPP_noinline");
    out.println("    #define JavaCPP_hidden");
    out.println("#endif");
    out.println();
    if (loadSuffix == null) {
        loadSuffix = "";
        String p = clsProperties.getProperty("platform.library.static", "false").toLowerCase();
        if (p.equals("true") || p.equals("t") || p.equals("")) {
            loadSuffix = "_" + clsProperties.getProperty("platform.library");
        }
    }
    if (classes != null) {
        List exclude = clsProperties.get("platform.exclude");
        List[] include = { clsProperties.get("platform.include"), clsProperties.get("platform.cinclude") };
        for (int i = 0; i < include.length; i++) {
            if (include[i] != null && include[i].size() > 0) {
                if (i == 1) {
                    out.println("extern \"C\" {");
                    if (out2 != null) {
                        out2.println("#ifdef __cplusplus");
                        out2.println("extern \"C\" {");
                        out2.println("#endif");
                    }
                }
                for (String s : (List<String>) include[i]) {
                    if (exclude.contains(s)) {
                        continue;
                    }
                    String line = "#include ";
                    if (!s.startsWith("<") && !s.startsWith("\"")) {
                        line += '"';
                    }
                    line += s;
                    if (!s.endsWith(">") && !s.endsWith("\"")) {
                        line += '"';
                    }
                    out.println(line);
                    if (out2 != null) {
                        out2.println(line);
                    }
                }
                if (i == 1) {
                    out.println("}");
                    if (out2 != null) {
                        out2.println("#ifdef __cplusplus");
                        out2.println("}");
                        out2.println("#endif");
                    }
                }
                out.println();
            }
        }
    }
    out.println("static JavaVM* JavaCPP_vm = NULL;");
    out.println("static bool JavaCPP_haveAllocObject = false;");
    out.println("static bool JavaCPP_haveNonvirtual = false;");
    out.println("static const char* JavaCPP_classNames[" + jclasses.size() + "] = {");
    Iterator<Class> classIterator = jclasses.iterator();
    int maxMemberSize = 0;
    while (classIterator.hasNext()) {
        Class c = classIterator.next();
        out.print("        \"" + c.getName().replace('.', '/') + "\"");
        if (classIterator.hasNext()) {
            out.println(",");
        }
        Set<String> m = members.get(c);
        if (m != null && m.size() > maxMemberSize) {
            maxMemberSize = m.size();
        }
    }
    out.println(" };");
    out.println("static jclass JavaCPP_classes[" + jclasses.size() + "] = { NULL };");
    out.println("static jfieldID JavaCPP_addressFID = NULL;");
    out.println("static jfieldID JavaCPP_positionFID = NULL;");
    out.println("static jfieldID JavaCPP_limitFID = NULL;");
    out.println("static jfieldID JavaCPP_capacityFID = NULL;");
    out.println("static jfieldID JavaCPP_deallocatorFID = NULL;");
    out.println("static jfieldID JavaCPP_ownerAddressFID = NULL;");
    if (declareEnums) {
        out.println("static jfieldID JavaCPP_byteValueFID = NULL;");
        out.println("static jfieldID JavaCPP_shortValueFID = NULL;");
        out.println("static jfieldID JavaCPP_intValueFID = NULL;");
        out.println("static jfieldID JavaCPP_longValueFID = NULL;");
    }
    out.println("static jmethodID JavaCPP_initMID = NULL;");
    out.println("static jmethodID JavaCPP_arrayMID = NULL;");
    out.println("static jmethodID JavaCPP_stringMID = NULL;");
    out.println("static jmethodID JavaCPP_getBytesMID = NULL;");
    out.println("static jmethodID JavaCPP_toStringMID = NULL;");
    out.println();
    out.println("static inline void JavaCPP_log(const char* fmt, ...) {");
    out.println("    va_list ap;");
    out.println("    va_start(ap, fmt);");
    out.println("#ifdef __ANDROID__");
    out.println("    __android_log_vprint(ANDROID_LOG_ERROR, \"javacpp\", fmt, ap);");
    out.println("#elif defined(__APPLE__) && defined(__OBJC__)");
    out.println("    NSLogv([NSString stringWithUTF8String:fmt], ap);");
    out.println("#else");
    out.println("    vfprintf(stderr, fmt, ap);");
    out.println("    fprintf(stderr, \"\\n\");");
    out.println("#endif");
    out.println("    va_end(ap);");
    out.println("}");
    out.println();
    if (baseLoadSuffix == null || baseLoadSuffix.isEmpty()) {
        out.println("static inline jboolean JavaCPP_trimMemory() {");
        out.println("#if defined(__linux__) && !defined(__ANDROID__)");
        out.println("    return (jboolean)malloc_trim(0);");
        out.println("#else");
        out.println("    return 0;");
        out.println("#endif");
        out.println("}");
        out.println();
        out.println("static inline jlong JavaCPP_physicalBytes() {");
        out.println("    jlong size = 0;");
        out.println("#ifdef __linux__");
        out.println("    static int fd = open(\"/proc/self/statm\", O_RDONLY, 0);");
        out.println("    if (fd >= 0) {");
        out.println("        char line[256];");
        out.println("        char* s;");
        out.println("        int n;");
        out.println("        if ((n = pread(fd, line, sizeof(line), 0)) > 0 && (s = (char*)memchr(line, ' ', n)) != NULL) {");
        out.println("            size = (jlong)(atoll(s + 1) * getpagesize());");
        out.println("        }");
        out.println("        // no close(fd);");
        out.println("    }");
        out.println("#elif defined(__APPLE__)");
        out.println("    task_basic_info info;");
        out.println("    mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;");
        out.println("    if (task_info(current_task(), TASK_BASIC_INFO, (task_info_t)&info, &count) == KERN_SUCCESS) {");
        out.println("        size = (jlong)info.resident_size;");
        out.println("    }");
        out.println("#elif defined(_WIN32)");
        out.println("    PROCESS_MEMORY_COUNTERS counters;");
        out.println("    if (GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters))) {");
        out.println("        size = (jlong)counters.WorkingSetSize;");
        out.println("    }");
        out.println("#endif");
        out.println("    return size;");
        out.println("}");
        out.println();
        out.println("static inline jlong JavaCPP_totalPhysicalBytes() {");
        out.println("    jlong size = 0;");
        out.println("#ifdef __linux__");
        out.println("    struct sysinfo info;");
        out.println("    if (sysinfo(&info) == 0) {");
        out.println("        size = info.totalram;");
        out.println("    }");
        out.println("#elif defined(__APPLE__)");
        out.println("    size_t length = sizeof(size);");
        out.println("    sysctlbyname(\"hw.memsize\", &size, &length, NULL, 0);");
        out.println("#elif defined(_WIN32)");
        out.println("    MEMORYSTATUSEX status;");
        out.println("    status.dwLength = sizeof(status);");
        out.println("    if (GlobalMemoryStatusEx(&status)) {");
        out.println("        size = status.ullTotalPhys;");
        out.println("    }");
        out.println("#endif");
        out.println("    return size;");
        out.println("}");
        out.println();
        out.println("static inline jlong JavaCPP_availablePhysicalBytes() {");
        out.println("    jlong size = 0;");
        out.println("#ifdef __linux__");
        out.println("    int fd = open(\"/proc/meminfo\", O_RDONLY, 0);");
        out.println("    if (fd >= 0) {");
        out.println("        char temp[4096];");
        out.println("        char *s;");
        out.println("        int n;");
        out.println("        if ((n = read(fd, temp, sizeof(temp))) > 0 && (s = (char*)memmem(temp, n, \"MemAvailable:\", 13)) != NULL) {");
        out.println("            size = (jlong)(atoll(s + 13) * 1024);");
        out.println("        }");
        out.println("        close(fd);");
        out.println("    }");
        out.println("    if (size == 0) {");
        out.println("        struct sysinfo info;");
        out.println("        if (sysinfo(&info) == 0) {");
        out.println("            size = info.freeram;");
        out.println("        }");
        out.println("    }");
        out.println("#elif defined(__APPLE__)");
        out.println("    vm_statistics_data_t info;");
        out.println("    mach_msg_type_number_t count = HOST_VM_INFO_COUNT;");
        out.println("    if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&info, &count) == KERN_SUCCESS) {");
        out.println("        size = (jlong)info.free_count * getpagesize();");
        out.println("    }");
        out.println("#elif defined(_WIN32)");
        out.println("    MEMORYSTATUSEX status;");
        out.println("    status.dwLength = sizeof(status);");
        out.println("    if (GlobalMemoryStatusEx(&status)) {");
        out.println("        size = status.ullAvailPhys;");
        out.println("    }");
        out.println("#endif");
        out.println("    return size;");
        out.println("}");
        out.println();
        out.println("static inline jint JavaCPP_totalProcessors() {");
        out.println("    jint total = 0;");
        out.println("#ifdef __linux__");
        out.println("    total = sysconf(_SC_NPROCESSORS_CONF);");
        out.println("#elif defined(__APPLE__)");
        out.println("    size_t length = sizeof(total);");
        out.println("    sysctlbyname(\"hw.logicalcpu_max\", &total, &length, NULL, 0);");
        out.println("#elif defined(_WIN32)");
        out.println("    SYSTEM_INFO info;");
        out.println("    GetSystemInfo(&info);");
        out.println("    total = info.dwNumberOfProcessors;");
        out.println("#endif");
        out.println("    return total;");
        out.println("}");
        out.println();
        out.println("static inline jint JavaCPP_totalCores() {");
        out.println("    jint total = 0;");
        out.println("#ifdef __linux__");
        out.println("    const int n = sysconf(_SC_NPROCESSORS_CONF);");
        out.println("    int pids[n], cids[n];");
        out.println("    for (int i = 0; i < n; i++) {");
        out.println("        int fd = 0, pid = 0, cid = 0;");
        out.println("        char temp[256];");
        out.println("        sprintf(temp, \"/sys/devices/system/cpu/cpu%d/topology/physical_package_id\", i);");
        out.println("        if ((fd = open(temp, O_RDONLY, 0)) >= 0) {");
        out.println("            if (read(fd, temp, sizeof(temp)) > 0) {");
        out.println("                pid = atoi(temp);");
        out.println("            }");
        out.println("            close(fd);");
        out.println("        }");
        out.println("        sprintf(temp, \"/sys/devices/system/cpu/cpu%d/topology/core_id\", i);");
        out.println("        if ((fd = open(temp, O_RDONLY, 0)) >= 0) {");
        out.println("            if (read(fd, temp, sizeof(temp)) > 0) {");
        out.println("                cid = atoi(temp);");
        out.println("            }");
        out.println("            close(fd);");
        out.println("        }");
        out.println("        bool found = false;");
        out.println("        for (int j = 0; j < total; j++) {");
        out.println("            if (pids[j] == pid && cids[j] == cid) {");
        out.println("                found = true;");
        out.println("                break;");
        out.println("            }");
        out.println("        }");
        out.println("        if (!found) {");
        out.println("            pids[total] = pid;");
        out.println("            cids[total] = cid;");
        out.println("            total++;");
        out.println("        }");
        out.println("    }");
        out.println("#elif defined(__APPLE__)");
        out.println("    size_t length = sizeof(total);");
        out.println("    sysctlbyname(\"hw.physicalcpu_max\", &total, &length, NULL, 0);");
        out.println("#elif defined(_WIN32)");
        out.println("    SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info = NULL;");
        out.println("    DWORD length = 0;");
        out.println("    BOOL success = GetLogicalProcessorInformation(info, &length);");
        out.println("    while (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {");
        out.println("        info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION*)realloc(info, length);");
        out.println("        success = GetLogicalProcessorInformation(info, &length);");
        out.println("    }");
        out.println("    if (success && info != NULL) {");
        out.println("        length /= sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);");
        out.println("        for (DWORD i = 0; i < length; i++) {");
        out.println("            if (info[i].Relationship == RelationProcessorCore) {");
        out.println("                total++;");
        out.println("            }");
        out.println("        }");
        out.println("    }");
        out.println("    free(info);");
        out.println("#endif");
        out.println("    return total;");
        out.println("}");
        out.println();
        out.println("static inline jint JavaCPP_totalChips() {");
        out.println("    jint total = 0;");
        out.println("#ifdef __linux__");
        out.println("    const int n = sysconf(_SC_NPROCESSORS_CONF);");
        out.println("    int pids[n];");
        out.println("    for (int i = 0; i < n; i++) {");
        out.println("        int fd = 0, pid = 0;");
        out.println("        char temp[256];");
        out.println("        sprintf(temp, \"/sys/devices/system/cpu/cpu%d/topology/physical_package_id\", i);");
        out.println("        if ((fd = open(temp, O_RDONLY, 0)) >= 0) {");
        out.println("            if (read(fd, temp, sizeof(temp)) > 0) {");
        out.println("                pid = atoi(temp);");
        out.println("            }");
        out.println("            close(fd);");
        out.println("        }");
        out.println("        bool found = false;");
        out.println("        for (int j = 0; j < total; j++) {");
        out.println("            if (pids[j] == pid) {");
        out.println("                found = true;");
        out.println("                break;");
        out.println("            }");
        out.println("        }");
        out.println("        if (!found) {");
        out.println("            pids[total] = pid;");
        out.println("            total++;");
        out.println("        }");
        out.println("    }");
        out.println("#elif defined(__APPLE__)");
        out.println("    size_t length = sizeof(total);");
        out.println("    sysctlbyname(\"hw.packages\", &total, &length, NULL, 0);");
        out.println("#elif defined(_WIN32)");
        out.println("    SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info = NULL;");
        out.println("    DWORD length = 0;");
        out.println("    BOOL success = GetLogicalProcessorInformation(info, &length);");
        out.println("    while (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {");
        out.println("        info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION*)realloc(info, length);");
        out.println("        success = GetLogicalProcessorInformation(info, &length);");
        out.println("    }");
        out.println("    if (success && info != NULL) {");
        out.println("        length /= sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);");
        out.println("        for (DWORD i = 0; i < length; i++) {");
        out.println("            if (info[i].Relationship == RelationProcessorPackage) {");
        out.println("                total++;");
        out.println("            }");
        out.println("        }");
        out.println("    }");
        out.println("    free(info);");
        out.println("#endif");
        out.println("    return total;");
        out.println("}");
        out.println();
        out.println("#if defined(__linux__) && !(defined(__ANDROID__) && defined(__arm__))");
        out.println("static int JavaCPP_dlcallback(dl_phdr_info *info, size_t size, void *data) {");
        out.println("    void *handle = dlopen(info->dlpi_name, RTLD_LAZY);");
        out.println("    if (handle != NULL) {");
        out.println("        void *address = dlsym(handle, ((char**)data)[0]);");
        out.println("        dlclose(handle);");
        out.println("        if (address != NULL) {");
        out.println("            ((void**)data)[1] = address;");
        out.println("            return 1;");
        out.println("        }");
        out.println("    }");
        out.println("    return 0;");
        out.println("}");
        out.println("#endif");
        out.println();
        out.println("static inline void* JavaCPP_addressof(const char* name) {");
        out.println("    void *address = NULL;");
        out.println("#ifdef __linux__");
        out.println("    address = dlsym(RTLD_DEFAULT, name);");
        out.println("#if !(defined(__ANDROID__) && defined(__arm__))");
        out.println("    if (address == NULL) {");
        out.println("        void *data[] = { (char*)name, NULL };");
        out.println("        dl_iterate_phdr(JavaCPP_dlcallback, data);");
        out.println("        address = data[1];");
        out.println("    }");
        out.println("#endif");
        out.println("#elif defined(__APPLE__)");
        out.println("    address = dlsym(RTLD_DEFAULT, name);");
        out.println("    if (address == NULL) {");
        out.println("        for (uint32_t i = 0; i < _dyld_image_count(); i++) {");
        out.println("            const char *libname = _dyld_get_image_name(i);");
        out.println("            if (libname != NULL) {");
        out.println("                void *handle = dlopen(libname, RTLD_LAZY);");
        out.println("                if (handle != NULL) {");
        out.println("                    address = dlsym(handle, name);");
        out.println("                    dlclose(handle);");
        out.println("                    if (address != NULL) {");
        out.println("                        break;");
        out.println("                    }");
        out.println("                }");
        out.println("            }");
        out.println("        }");
        out.println("    }");
        out.println("#elif defined(_WIN32)");
        out.println("    HANDLE process = GetCurrentProcess();");
        out.println("    HMODULE *modules = NULL;");
        out.println("    DWORD length = 0, needed = 0;");
        out.println("    BOOL success = EnumProcessModules(process, modules, length, &needed);");
        out.println("    while (success && needed > length) {");
        out.println("        modules = (HMODULE*)realloc(modules, length = needed);");
        out.println("        success = EnumProcessModules(process, modules, length, &needed);");
        out.println("    }");
        out.println("    if (success && modules != NULL) {");
        out.println("        length = needed / sizeof(HMODULE);");
        out.println("        for (DWORD i = 0; i < length; i++) {");
        out.println("            address = (void*)GetProcAddress(modules[i], name);");
        out.println("            if (address != NULL) {");
        out.println("                break;");
        out.println("            }");
        out.println("        }");
        out.println("    }");
        out.println("    free(modules);");
        out.println("#endif");
        out.println("    return address;");
        out.println("}");
        out.println();
    }
    out.println("static JavaCPP_noinline jclass JavaCPP_getClass(JNIEnv* env, int i) {");
    out.println("    if (JavaCPP_classes[i] == NULL && env->PushLocalFrame(1) == 0) {");
    out.println("        jclass cls = env->FindClass(JavaCPP_classNames[i]);");
    out.println("        if (cls == NULL || env->ExceptionCheck()) {");
    out.println("            JavaCPP_log(\"Error loading class %s.\", JavaCPP_classNames[i]);");
    out.println("            return NULL;");
    out.println("        }");
    out.println("        JavaCPP_classes[i] = (jclass)env->NewWeakGlobalRef(cls);");
    out.println("        if (JavaCPP_classes[i] == NULL || env->ExceptionCheck()) {");
    out.println("            JavaCPP_log(\"Error creating global reference of class %s.\", JavaCPP_classNames[i]);");
    out.println("            return NULL;");
    out.println("        }");
    out.println("        env->PopLocalFrame(NULL);");
    out.println("    }");
    out.println("    return JavaCPP_classes[i];");
    out.println("}");
    out.println();
    out.println("static JavaCPP_noinline jfieldID JavaCPP_getFieldID(JNIEnv* env, int i, const char* name, const char* sig) {");
    out.println("    jclass cls = JavaCPP_getClass(env, i);");
    out.println("    if (cls == NULL) {");
    out.println("        return NULL;");
    out.println("    }");
    out.println("    jfieldID fid = env->GetFieldID(cls, name, sig);");
    out.println("    if (fid == NULL || env->ExceptionCheck()) {");
    out.println("        JavaCPP_log(\"Error getting field ID of %s/%s\", JavaCPP_classNames[i], name);");
    out.println("        return NULL;");
    out.println("    }");
    out.println("    return fid;");
    out.println("}");
    out.println();
    if (declareEnums) {
        out.println("static JavaCPP_noinline jfieldID JavaCPP_getFieldID(JNIEnv* env, const char* clsName, const char* name, const char* sig) {");
        out.println("    jclass cls = env->FindClass(clsName);");
        out.println("    if (cls == NULL || env->ExceptionCheck()) {");
        out.println("        JavaCPP_log(\"Error loading class %s.\", clsName);");
        out.println("        return NULL;");
        out.println("    }");
        out.println("    jfieldID fid = env->GetFieldID(cls, name, sig);");
        out.println("    if (fid == NULL || env->ExceptionCheck()) {");
        out.println("        JavaCPP_log(\"Error getting field ID of %s/%s\", clsName, name);");
        out.println("        return NULL;");
        out.println("    }");
        out.println("    return fid;");
        out.println("}");
        out.println();
    }
    out.println("static JavaCPP_noinline jmethodID JavaCPP_getMethodID(JNIEnv* env, int i, const char* name, const char* sig) {");
    out.println("    jclass cls = JavaCPP_getClass(env, i);");
    out.println("    if (cls == NULL) {");
    out.println("        return NULL;");
    out.println("    }");
    out.println("    jmethodID mid = env->GetMethodID(cls, name, sig);");
    out.println("    if (mid == NULL || env->ExceptionCheck()) {");
    out.println("        JavaCPP_log(\"Error getting method ID of %s/%s\", JavaCPP_classNames[i], name);");
    out.println("        return NULL;");
    out.println("    }");
    out.println("    return mid;");
    out.println("}");
    out.println();
    out.println("static JavaCPP_noinline jmethodID JavaCPP_getStaticMethodID(JNIEnv* env, int i, const char* name, const char* sig) {");
    out.println("    jclass cls = JavaCPP_getClass(env, i);");
    out.println("    if (cls == NULL) {");
    out.println("        return NULL;");
    out.println("    }");
    out.println("    jmethodID mid = env->GetStaticMethodID(cls, name, sig);");
    out.println("    if (mid == NULL || env->ExceptionCheck()) {");
    out.println("        JavaCPP_log(\"Error getting static method ID of %s/%s\", JavaCPP_classNames[i], name);");
    out.println("        return NULL;");
    out.println("    }");
    out.println("    return mid;");
    out.println("}");
    out.println();
    out.println("static JavaCPP_noinline jobject JavaCPP_createPointer(JNIEnv* env, int i, jclass cls = NULL) {");
    out.println("    if (cls == NULL && (cls = JavaCPP_getClass(env, i)) == NULL) {");
    out.println("        return NULL;");
    out.println("    }");
    out.println("    if (JavaCPP_haveAllocObject) {");
    out.println("        return env->AllocObject(cls);");
    out.println("    } else {");
    out.println("        jmethodID mid = env->GetMethodID(cls, \"<init>\", \"(Lorg/bytedeco/javacpp/Pointer;)V\");");
    out.println("        if (mid == NULL || env->ExceptionCheck()) {");
    out.println("            JavaCPP_log(\"Error getting Pointer constructor of %s, while VM does not support AllocObject()\", JavaCPP_classNames[i]);");
    out.println("            return NULL;");
    out.println("        }");
    out.println("        return env->NewObject(cls, mid, NULL);");
    out.println("    }");
    out.println("}");
    out.println();
    out.println("static JavaCPP_noinline void JavaCPP_initPointer(JNIEnv* env, jobject obj, const void* ptr, jlong size, void* owner, void (*deallocator)(void*)) {");
    out.println("    if (deallocator != NULL) {");
    out.println("        jvalue args[4];");
    out.println("        args[0].j = ptr_to_jlong(ptr);");
    out.println("        args[1].j = size;");
    out.println("        args[2].j = ptr_to_jlong(owner);");
    out.println("        args[3].j = ptr_to_jlong(deallocator);");
    out.println("        if (JavaCPP_haveNonvirtual) {");
    out.println("            env->CallNonvirtualVoidMethodA(obj, JavaCPP_getClass(env, " + jclasses.index(Pointer.class) + "), JavaCPP_initMID, args);");
    out.println("        } else {");
    out.println("            env->CallVoidMethodA(obj, JavaCPP_initMID, args);");
    out.println("        }");
    out.println("    } else {");
    out.println("        env->SetLongField(obj, JavaCPP_addressFID, ptr_to_jlong(ptr));");
    out.println("        env->SetLongField(obj, JavaCPP_limitFID, (jlong)size);");
    out.println("        env->SetLongField(obj, JavaCPP_capacityFID, (jlong)size);");
    out.println("    }");
    out.println("}");
    out.println();
    if (handleExceptions || convertStrings) {
        out.println("static JavaCPP_noinline jstring JavaCPP_createString(JNIEnv* env, const char* ptr) {");
        out.println("    if (ptr == NULL) {");
        out.println("        return NULL;");
        out.println("    }");
        out.println("#ifdef MODIFIED_UTF8_STRING");
        out.println("    return env->NewStringUTF(ptr);");
        out.println("#else");
        out.println("    size_t length = strlen(ptr);");
        out.println("    jbyteArray bytes = env->NewByteArray(length < INT_MAX ? length : INT_MAX);");
        out.println("    env->SetByteArrayRegion(bytes, 0, length < INT_MAX ? length : INT_MAX, (signed char*)ptr);");
        out.println("    return (jstring)env->NewObject(JavaCPP_getClass(env, " + jclasses.index(String.class) + "), JavaCPP_stringMID, bytes);");
        out.println("#endif");
        out.println("}");
        out.println();
    }
    if (convertStrings) {
        out.println("static JavaCPP_noinline const char* JavaCPP_getStringBytes(JNIEnv* env, jstring str) {");
        out.println("    if (str == NULL) {");
        out.println("        return NULL;");
        out.println("    }");
        out.println("#ifdef MODIFIED_UTF8_STRING");
        out.println("    return env->GetStringUTFChars(str, NULL);");
        out.println("#else");
        out.println("    jbyteArray bytes = (jbyteArray)env->CallObjectMethod(str, JavaCPP_getBytesMID);");
        out.println("    if (bytes == NULL || env->ExceptionCheck()) {");
        out.println("        JavaCPP_log(\"Error getting bytes from string.\");");
        out.println("        return NULL;");
        out.println("    }");
        out.println("    jsize length = env->GetArrayLength(bytes);");
        out.println("    signed char* ptr = new (std::nothrow) signed char[length + 1];");
        out.println("    if (ptr != NULL) {");
        out.println("        env->GetByteArrayRegion(bytes, 0, length, ptr);");
        out.println("        ptr[length] = 0;");
        out.println("    }");
        out.println("    return (const char*)ptr;");
        out.println("#endif");
        out.println("}");
        out.println();
        out.println("static JavaCPP_noinline void JavaCPP_releaseStringBytes(JNIEnv* env, jstring str, const char* ptr) {");
        out.println("#ifdef MODIFIED_UTF8_STRING");
        out.println("    if (str != NULL) {");
        out.println("        env->ReleaseStringUTFChars(str, ptr);");
        out.println("    }");
        out.println("#else");
        out.println("    delete[] ptr;");
        out.println("#endif");
        out.println("}");
        out.println();
    }
    out.println("class JavaCPP_hidden JavaCPP_exception : public std::exception {");
    out.println("public:");
    out.println("    JavaCPP_exception(const char* str) throw() {");
    out.println("        if (str == NULL) {");
    out.println("            strcpy(msg, \"Unknown exception.\");");
    out.println("        } else {");
    out.println("            strncpy(msg, str, sizeof(msg));");
    out.println("            msg[sizeof(msg) - 1] = 0;");
    out.println("        }");
    out.println("    }");
    out.println("    virtual const char* what() const throw() { return msg; }");
    out.println("    char msg[1024];");
    out.println("};");
    out.println();
    if (handleExceptions) {
        out.println("#ifndef GENERIC_EXCEPTION_CLASS");
        out.println("#define GENERIC_EXCEPTION_CLASS std::exception");
        out.println("#endif");
        out.println("static JavaCPP_noinline jthrowable JavaCPP_handleException(JNIEnv* env, int i) {");
        out.println("    jstring str = NULL;");
        out.println("    try {");
        out.println("        throw;");
        out.println("    } catch (GENERIC_EXCEPTION_CLASS& e) {");
        out.println("        str = JavaCPP_createString(env, e.what());");
        out.println("    } catch (...) {");
        out.println("        str = JavaCPP_createString(env, \"Unknown exception.\");");
        out.println("    }");
        out.println("    jmethodID mid = JavaCPP_getMethodID(env, i, \"<init>\", \"(Ljava/lang/String;)V\");");
        out.println("    if (mid == NULL) {");
        out.println("        return NULL;");
        out.println("    }");
        out.println("    return (jthrowable)env->NewObject(JavaCPP_getClass(env, i), mid, str);");
        out.println("}");
        out.println();
    }
    Class deallocator, nativeDeallocator;
    try {
        deallocator = Class.forName(Pointer.class.getName() + "$Deallocator", false, Pointer.class.getClassLoader());
        nativeDeallocator = Class.forName(Pointer.class.getName() + "$NativeDeallocator", false, Pointer.class.getClassLoader());
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(ex);
    }
    if (defineAdapters) {
        out.println("static JavaCPP_noinline void* JavaCPP_getPointerOwner(JNIEnv* env, jobject obj) {");
        out.println("    if (obj != NULL) {");
        out.println("        jobject deallocator = env->GetObjectField(obj, JavaCPP_deallocatorFID);");
        out.println("        if (deallocator != NULL && env->IsInstanceOf(deallocator, JavaCPP_getClass(env, " + jclasses.index(nativeDeallocator) + "))) {");
        out.println("            return jlong_to_ptr(env->GetLongField(deallocator, JavaCPP_ownerAddressFID));");
        out.println("        }");
        out.println("    }");
        out.println("    return NULL;");
        out.println("}");
        out.println();
        out.println("#include <vector>");
        out.println("template<typename P, typename T = P> class JavaCPP_hidden VectorAdapter {");
        out.println("public:");
        out.println("    VectorAdapter(const P* ptr, typename std::vector<T>::size_type size, void* owner) : ptr((P*)ptr), size(size), owner(owner),");
        out.println("        vec2(ptr ? std::vector<T>((P*)ptr, (P*)ptr + size) : std::vector<T>()), vec(vec2) { }");
        out.println("    VectorAdapter(const std::vector<T>& vec) : ptr(0), size(0), owner(0), vec2(vec), vec(vec2) { }");
        out.println("    VectorAdapter(      std::vector<T>& vec) : ptr(0), size(0), owner(0), vec(vec) { }");
        out.println("    VectorAdapter(const std::vector<T>* vec) : ptr(0), size(0), owner(0), vec(*(std::vector<T>*)vec) { }");
        out.println("    void assign(P* ptr, typename std::vector<T>::size_type size, void* owner) {");
        out.println("        this->ptr = ptr;");
        out.println("        this->size = size;");
        out.println("        this->owner = owner;");
        out.println("        vec.assign(ptr, ptr + size);");
        out.println("    }");
        out.println("    static void deallocate(void* owner) { operator delete(owner); }");
        out.println("    operator P*() {");
        out.println("        if (vec.size() > size) {");
        out.println("            ptr = (P*)(operator new(sizeof(P) * vec.size(), std::nothrow_t()));");
        out.println("        }");
        out.println("        if (ptr) {");
        out.println("            std::copy(vec.begin(), vec.end(), ptr);");
        out.println("        }");
        out.println("        size = vec.size();");
        out.println("        owner = ptr;");
        out.println("        return ptr;");
        out.println("    }");
        out.println("    operator const P*()        { return &vec[0]; }");
        out.println("    operator std::vector<T>&() { return vec; }");
        out.println("    operator std::vector<T>*() { return ptr ? &vec : 0; }");
        out.println("    P* ptr;");
        out.println("    typename std::vector<T>::size_type size;");
        out.println("    void* owner;");
        out.println("    std::vector<T> vec2;");
        out.println("    std::vector<T>& vec;");
        out.println("};");
        out.println();
        out.println("#include <string>");
        out.println("class JavaCPP_hidden StringAdapter {");
        out.println("public:");
        out.println("    StringAdapter(const          char* ptr, size_t size, void* owner) : ptr((char*)ptr), size(size), owner(owner),");
        out.println("        str2(ptr ? (char*)ptr : \"\", ptr ? (size > 0 ? size : strlen((char*)ptr)) : 0), str(str2) { }");
        out.println("    StringAdapter(const signed   char* ptr, size_t size, void* owner) : ptr((char*)ptr), size(size), owner(owner),");
        out.println("        str2(ptr ? (char*)ptr : \"\", ptr ? (size > 0 ? size : strlen((char*)ptr)) : 0), str(str2) { }");
        out.println("    StringAdapter(const unsigned char* ptr, size_t size, void* owner) : ptr((char*)ptr), size(size), owner(owner),");
        out.println("        str2(ptr ? (char*)ptr : \"\", ptr ? (size > 0 ? size : strlen((char*)ptr)) : 0), str(str2) { }");
        out.println("    StringAdapter(const std::string& str) : ptr(0), size(0), owner(0), str2(str), str(str2) { }");
        out.println("    StringAdapter(      std::string& str) : ptr(0), size(0), owner(0), str(str) { }");
        out.println("    StringAdapter(const std::string* str) : ptr(0), size(0), owner(0), str(*(std::string*)str) { }");
        out.println("    void assign(char* ptr, size_t size, void* owner) {");
        out.println("        this->ptr = ptr;");
        out.println("        this->size = size;");
        out.println("        this->owner = owner;");
        out.println("        str.assign(ptr ? ptr : \"\", ptr ? (size > 0 ? size : strlen((char*)ptr)) : 0);");
        out.println("    }");
        out.println("    void assign(const          char* ptr, size_t size, void* owner) { assign((char*)ptr, size, owner); }");
        out.println("    void assign(const signed   char* ptr, size_t size, void* owner) { assign((char*)ptr, size, owner); }");
        out.println("    void assign(const unsigned char* ptr, size_t size, void* owner) { assign((char*)ptr, size, owner); }");
        out.println("    static void deallocate(void* owner) { delete[] (char*)owner; }");
        out.println("    operator char*() {");
        out.println("        const char* data = str.data();");
        out.println("        if (str.size() > size) {");
        out.println("            ptr = new (std::nothrow) char[str.size()+1];");
        out.println("            if (ptr) memset(ptr, 0, str.size()+1);");
        out.println("        }");
        out.println("        if (ptr && memcmp(ptr, data, str.size()) != 0) {");
        out.println("            memcpy(ptr, data, str.size());");
        out.println("            if (size > str.size()) ptr[str.size()] = 0;");
        out.println("        }");
        out.println("        size = str.size();");
        out.println("        owner = ptr;");
        out.println("        return ptr;");
        out.println("    }");
        out.println("    operator       signed   char*() { return (signed   char*)(operator char*)(); }");
        out.println("    operator       unsigned char*() { return (unsigned char*)(operator char*)(); }");
        out.println("    operator const          char*() { return                 str.c_str(); }");
        out.println("    operator const signed   char*() { return (signed   char*)str.c_str(); }");
        out.println("    operator const unsigned char*() { return (unsigned char*)str.c_str(); }");
        out.println("    operator         std::string&() { return str; }");
        out.println("    operator         std::string*() { return ptr ? &str : 0; }");
        out.println("    char* ptr;");
        out.println("    size_t size;");
        out.println("    void* owner;");
        out.println("    std::string str2;");
        out.println("    std::string& str;");
        out.println("};");
        out.println();
        out.println("#ifdef SHARED_PTR_NAMESPACE");
        out.println("template<class T> class SharedPtrAdapter {");
        out.println("public:");
        out.println("    typedef SHARED_PTR_NAMESPACE::shared_ptr<T> S;");
        out.println("    SharedPtrAdapter(const T* ptr, size_t size, void* owner) : ptr((T*)ptr), size(size), owner(owner),");
        out.println("            sharedPtr2(owner != NULL && owner != ptr ? *(S*)owner : S((T*)ptr)), sharedPtr(sharedPtr2) { }");
        out.println("    SharedPtrAdapter(const S& sharedPtr) : ptr(0), size(0), owner(0), sharedPtr2(sharedPtr), sharedPtr(sharedPtr2) { }");
        out.println("    SharedPtrAdapter(      S& sharedPtr) : ptr(0), size(0), owner(0), sharedPtr(sharedPtr) { }");
        out.println("    SharedPtrAdapter(const S* sharedPtr) : ptr(0), size(0), owner(0), sharedPtr(*(S*)sharedPtr) { }");
        out.println("    void assign(T* ptr, size_t size, S* owner) {");
        out.println("        this->ptr = ptr;");
        out.println("        this->size = size;");
        out.println("        this->owner = owner;");
        out.println("        this->sharedPtr = owner != NULL && owner != ptr ? *(S*)owner : S((T*)ptr);");
        out.println("    }");
        out.println("    static void deallocate(void* owner) { delete (S*)owner; }");
        out.println("    operator typename SHARED_PTR_NAMESPACE::remove_const<T>::type*() {");
        out.println("        ptr = sharedPtr.get();");
        out.println("        if (owner == NULL || owner == ptr) {");
        out.println("            owner = new S(sharedPtr);");
        out.println("        }");
        out.println("        return (typename SHARED_PTR_NAMESPACE::remove_const<T>::type*)ptr;");
        out.println("    }");
        out.println("    operator S&() { return sharedPtr; }");
        out.println("    operator S*() { return &sharedPtr; }");
        out.println("    T* ptr;");
        out.println("    size_t size;");
        out.println("    void* owner;");
        out.println("    S sharedPtr2;");
        out.println("    S& sharedPtr;");
        out.println("};");
        out.println("#endif");
        out.println();
        out.println("#ifdef UNIQUE_PTR_NAMESPACE");
        out.println("template<class T> class UniquePtrAdapter {");
        out.println("public:");
        out.println("    typedef UNIQUE_PTR_NAMESPACE::unique_ptr<T> U;");
        out.println("    UniquePtrAdapter(const T* ptr, size_t size, void* owner) : ptr((T*)ptr), size(size), owner(owner),");
        out.println("            uniquePtr2(owner != NULL && owner != ptr ? U() : U((T*)ptr)),");
        out.println("            uniquePtr(owner != NULL && owner != ptr ? *(U*)owner : uniquePtr2) { }");
        out.println("    UniquePtrAdapter(U&& uniquePtr) : ptr(0), size(0), owner(0), uniquePtr2(UNIQUE_PTR_NAMESPACE::move(uniquePtr)), uniquePtr(uniquePtr2) { }");
        out.println("    UniquePtrAdapter(const U& uniquePtr) : ptr(0), size(0), owner(0), uniquePtr((U&)uniquePtr) { }");
        out.println("    UniquePtrAdapter(      U& uniquePtr) : ptr(0), size(0), owner(0), uniquePtr(uniquePtr) { }");
        out.println("    UniquePtrAdapter(const U* uniquePtr) : ptr(0), size(0), owner(0), uniquePtr(*(U*)uniquePtr) { }");
        out.println("    void assign(T* ptr, size_t size, U* owner) {");
        out.println("        this->ptr = ptr;");
        out.println("        this->size = size;");
        out.println("        this->owner = owner;");
        out.println("        this->uniquePtr = owner != NULL && owner != ptr ? *(U*)owner : U((T*)ptr);");
        out.println("    }");
        out.println("    static void deallocate(void* owner) { delete (U*)owner; }");
        out.println("    operator typename UNIQUE_PTR_NAMESPACE::remove_const<T>::type*() {");
        out.println("        ptr = uniquePtr.get();");
        out.println("        if (ptr == uniquePtr2.get() && (owner == NULL || owner == ptr)) {");
        out.println("            // only move the pointer if we actually own it through uniquePtr2");
        out.println("            owner = new U(UNIQUE_PTR_NAMESPACE::move(uniquePtr));");
        out.println("        }");
        out.println("        return (typename UNIQUE_PTR_NAMESPACE::remove_const<T>::type*)ptr;");
        out.println("    }");
        out.println("    operator U&() { return uniquePtr; }");
        out.println("    operator U*() { return &uniquePtr; }");
        out.println("    T* ptr;");
        out.println("    size_t size;");
        out.println("    void* owner;");
        out.println("    U uniquePtr2;");
        out.println("    U& uniquePtr;");
        out.println("};");
        out.println("#endif");
        out.println();
    }
    if (!functions.isEmpty() || !virtualFunctions.isEmpty()) {
        out.println("static JavaCPP_noinline void JavaCPP_detach(bool detach) {");
        out.println("#ifndef NO_JNI_DETACH_THREAD");
        out.println("    if (detach && JavaCPP_vm->DetachCurrentThread() != JNI_OK) {");
        out.println("        JavaCPP_log(\"Could not detach the JavaVM from the current thread.\");");
        out.println("    }");
        out.println("#endif");
        out.println("}");
        out.println();
        if (!loadSuffix.isEmpty()) {
            out.println("extern \"C\" {");
            out.println("JNIEXPORT jint JNICALL JNI_OnLoad" + loadSuffix + "(JavaVM* vm, void* reserved);");
            out.println("}");
        }
        out.println("static JavaCPP_noinline bool JavaCPP_getEnv(JNIEnv** env) {");
        out.println("    bool attached = false;");
        out.println("    JavaVM *vm = JavaCPP_vm;");
        out.println("    if (vm == NULL) {");
        if (out2 != null) {
            out.println("#if !defined(__ANDROID__) && !TARGET_OS_IPHONE");
            out.println("        int size = 1;");
            out.println("        if (JNI_GetCreatedJavaVMs(&vm, 1, &size) != JNI_OK || size == 0) {");
            out.println("#endif");
        }
        out.println("            JavaCPP_log(\"Could not get any created JavaVM.\");");
        out.println("            *env = NULL;");
        out.println("            return false;");
        if (out2 != null) {
            out.println("#if !defined(__ANDROID__) && !TARGET_OS_IPHONE");
            out.println("        }");
            out.println("#endif");
        }
        out.println("    }");
        out.println("    if (vm->GetEnv((void**)env, " + JNI_VERSION + ") != JNI_OK) {");
        out.println("        struct {");
        out.println("            JNIEnv **env;");
        out.println("            operator JNIEnv**() { return env; } // Android JNI");
        out.println("            operator void**() { return (void**)env; } // standard JNI");
        out.println("        } env2 = { env };");
        out.println("        if (vm->AttachCurrentThread(env2, NULL) != JNI_OK) {");
        out.println("            JavaCPP_log(\"Could not attach the JavaVM to the current thread.\");");
        out.println("            *env = NULL;");
        out.println("            return false;");
        out.println("        }");
        out.println("        attached = true;");
        out.println("    }");
        out.println("    if (JavaCPP_vm == NULL) {");
        out.println("        if (JNI_OnLoad" + loadSuffix + "(vm, NULL) < 0) {");
        out.println("            JavaCPP_detach(attached);");
        out.println("            *env = NULL;");
        out.println("            return false;");
        out.println("        }");
        out.println("    }");
        out.println("    return attached;");
        out.println("}");
        out.println();
    }
    for (Class c : functions) {
        String[] typeName = cppTypeName(c);
        String[] returnConvention = typeName[0].split("\\(");
        returnConvention[1] = constValueTypeName(returnConvention[1]);
        String parameterDeclaration = typeName[1].substring(1);
        String instanceTypeName = functionClassName(c);
        out.println("struct JavaCPP_hidden " + instanceTypeName + " {");
        out.println("    " + instanceTypeName + "() : ptr(NULL), obj(NULL) { }");
        if (parameterDeclaration != null && parameterDeclaration.length() > 0) {
            out.println("    " + returnConvention[0] + "operator()" + parameterDeclaration + ";");
        }
        out.println("    " + typeName[0] + "ptr" + typeName[1] + ";");
        out.println("    jobject obj; static jmethodID mid;");
        out.println("};");
        out.println("jmethodID " + instanceTypeName + "::mid = NULL;");
    }
    out.println();
    for (Class c : jclasses) {
        Set<String> functionList = virtualFunctions.get(c);
        if (functionList == null) {
            continue;
        }
        Set<String> memberList = virtualMembers.get(c);
        String[] typeName = cppTypeName(c);
        String valueTypeName = valueTypeName(typeName);
        String subType = "JavaCPP_" + mangle(valueTypeName);
        out.println("class JavaCPP_hidden " + subType + " : public " + valueTypeName + " {");
        out.println("public:");
        out.println("    jobject obj;");
        for (String s : functionList) {
            out.println("    static jmethodID " + s + ";");
        }
        out.println();
        for (String s : memberList) {
            out.println(s);
        }
        out.println("};");
        for (String s : functionList) {
            out.println("jmethodID " + subType + "::" + s + " = NULL;");
        }
    }
    out.println();
    for (String s : callbacks) {
        out.println(s);
    }
    out.println();
    for (Class c : deallocators) {
        String name = "JavaCPP_" + mangle(c.getName());
        out.print("static void " + name + "_deallocate(void *p) { ");
        if (FunctionPointer.class.isAssignableFrom(c)) {
            String typeName = functionClassName(c) + "*";
            out.println("JNIEnv *e; bool a = JavaCPP_getEnv(&e); if (e != NULL) e->DeleteWeakGlobalRef((jweak)((" + typeName + ")p)->obj); delete (" + typeName + ")p; JavaCPP_detach(a); }");
        } else if (virtualFunctions.containsKey(c)) {
            String[] typeName = cppTypeName(c);
            String valueTypeName = valueTypeName(typeName);
            String subType = "JavaCPP_" + mangle(valueTypeName);
            out.println("JNIEnv *e; bool a = JavaCPP_getEnv(&e); if (e != NULL) e->DeleteWeakGlobalRef((jweak)((" + subType + "*)p)->obj); delete (" + subType + "*)p; JavaCPP_detach(a); }");
        } else {
            String[] typeName = cppTypeName(c);
            out.println("delete (" + typeName[0] + typeName[1] + ")p; }");
        }
    }
    for (Class c : arrayDeallocators) {
        String name = "JavaCPP_" + mangle(c.getName());
        String[] typeName = cppTypeName(c);
        out.println("static void " + name + "_deallocateArray(void* p) { delete[] (" + typeName[0] + typeName[1] + ")p; }");
    }
    out.println();
    out.println("static const char* JavaCPP_members[" + jclasses.size() + "][" + maxMemberSize + 1 + "] = {");
    classIterator = jclasses.iterator();
    while (classIterator.hasNext()) {
        out.print("        { ");
        Set<String> m = members.get(classIterator.next());
        Iterator<String> memberIterator = m == null ? null : m.iterator();
        if (memberIterator == null || !memberIterator.hasNext()) {
            out.print("NULL");
        } else
            while (memberIterator.hasNext()) {
                out.print("\"" + memberIterator.next() + "\"");
                if (memberIterator.hasNext()) {
                    out.print(", ");
                }
            }
        out.print(" }");
        if (classIterator.hasNext()) {
            out.println(",");
        }
    }
    out.println(" };");
    out.println("static int JavaCPP_offsets[" + jclasses.size() + "][" + maxMemberSize + 1 + "] = {");
    classIterator = jclasses.iterator();
    while (classIterator.hasNext()) {
        out.print("        { ");
        Class c = classIterator.next();
        Set<String> m = members.get(c);
        Iterator<String> memberIterator = m == null ? null : m.iterator();
        if (memberIterator == null || !memberIterator.hasNext()) {
            out.print("-1");
        } else
            while (memberIterator.hasNext()) {
                String[] typeName = cppTypeName(c);
                String valueTypeName = valueTypeName(typeName);
                String memberName = memberIterator.next();
                if ("sizeof".equals(memberName)) {
                    if ("void".equals(valueTypeName)) {
                        valueTypeName = "void*";
                    }
                    out.print("sizeof(" + valueTypeName + ")");
                } else {
                    out.print("offsetof(" + valueTypeName + ", " + memberName + ")");
                }
                if (memberIterator.hasNext()) {
                    out.print(", ");
                }
            }
        out.print(" }");
        if (classIterator.hasNext()) {
            out.println(",");
        }
    }
    out.println(" };");
    out.print("static int JavaCPP_memberOffsetSizes[" + jclasses.size() + "] = { ");
    classIterator = jclasses.iterator();
    while (classIterator.hasNext()) {
        Set<String> m = members.get(classIterator.next());
        out.print(m == null ? 1 : m.size());
        if (classIterator.hasNext()) {
            out.print(", ");
        }
    }
    out.println(" };");
    out.println();
    out.println("extern \"C\" {");
    if (out2 != null) {
        out2.println();
        out2.println("#ifdef __cplusplus");
        out2.println("extern \"C\" {");
        out2.println("#endif");
        out2.println("JNIIMPORT int JavaCPP_init" + loadSuffix + "(int argc, const char *argv[]);");
        out.println();
        out.println("JNIEXPORT int JavaCPP_init" + loadSuffix + "(int argc, const char *argv[]) {");
        out.println("#if defined(__ANDROID__) || TARGET_OS_IPHONE");
        out.println("    return JNI_OK;");
        out.println("#else");
        out.println("    if (JavaCPP_vm != NULL) {");
        out.println("        return JNI_OK;");
        out.println("    }");
        out.println("    int err;");
        out.println("    JavaVM *vm;");
        out.println("    JNIEnv *env;");
        out.println("    int nOptions = 1 + (argc > 255 ? 255 : argc);");
        out.println("    JavaVMOption options[256] = { { NULL } };");
        out.println("    options[0].optionString = (char*)\"-Djava.class.path=" + classPath.replace('\\', '/') + "\";");
        out.println("    for (int i = 1; i < nOptions && argv != NULL; i++) {");
        out.println("        options[i].optionString = (char*)argv[i - 1];");
        out.println("    }");
        out.println("    JavaVMInitArgs vm_args = { " + JNI_VERSION + ", nOptions, options };");
        out.println("    return (err = JNI_CreateJavaVM(&vm, (void**)&env, &vm_args)) == JNI_OK && vm != NULL && (err = JNI_OnLoad" + loadSuffix + "(vm, NULL)) >= 0 ? JNI_OK : err;");
        out.println("#endif");
        out.println("}");
    }
    if (baseLoadSuffix != null && !baseLoadSuffix.isEmpty()) {
        out.println();
        out.println("JNIEXPORT jint JNICALL JNI_OnLoad" + baseLoadSuffix + "(JavaVM* vm, void* reserved);");
        out.println("JNIEXPORT void JNICALL JNI_OnUnload" + baseLoadSuffix + "(JavaVM* vm, void* reserved);");
    }
    // XXX: JNI_OnLoad() should ideally be protected by some mutex
    out.println();
    out.println("JNIEXPORT jint JNICALL JNI_OnLoad" + loadSuffix + "(JavaVM* vm, void* reserved) {");
    if (baseLoadSuffix != null && !baseLoadSuffix.isEmpty()) {
        out.println("    if (JNI_OnLoad" + baseLoadSuffix + "(vm, reserved) == JNI_ERR) {");
        out.println("        return JNI_ERR;");
        out.println("    }");
    }
    out.println("    JNIEnv* env;");
    out.println("    if (vm->GetEnv((void**)&env, " + JNI_VERSION + ") != JNI_OK) {");
    out.println("        JavaCPP_log(\"Could not get JNIEnv for " + JNI_VERSION + " inside JNI_OnLoad" + loadSuffix + "().\");");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    if (JavaCPP_vm == vm) {");
    out.println("        return env->GetVersion();");
    out.println("    }");
    out.println("    JavaCPP_vm = vm;");
    out.println("    JavaCPP_haveAllocObject = env->functions->AllocObject != NULL;");
    out.println("    JavaCPP_haveNonvirtual = env->functions->CallNonvirtualVoidMethodA != NULL;");
    out.println("    jmethodID putMemberOffsetMID = JavaCPP_getStaticMethodID(env, " + jclasses.index(Loader.class) + ", \"putMemberOffset\", \"(Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/Class;\");");
    out.println("    if (putMemberOffsetMID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    for (int i = 0; i < " + jclasses.size() + " && !env->ExceptionCheck(); i++) {");
    out.println("        for (int j = 0; j < JavaCPP_memberOffsetSizes[i] && !env->ExceptionCheck(); j++) {");
    out.println("            if (env->PushLocalFrame(3) == 0) {");
    out.println("                jvalue args[3];");
    out.println("                args[0].l = env->NewStringUTF(JavaCPP_classNames[i]);");
    out.println("                args[1].l = JavaCPP_members[i][j] == NULL ? NULL : env->NewStringUTF(JavaCPP_members[i][j]);");
    out.println("                args[2].i = JavaCPP_offsets[i][j];");
    out.println("                jclass cls = (jclass)env->CallStaticObjectMethodA(JavaCPP_getClass(env, " + jclasses.index(Loader.class) + "), putMemberOffsetMID, args);");
    out.println("                if (env->ExceptionCheck()) {");
    out.println("                    JavaCPP_log(\"Error putting member offsets for class %s.\", JavaCPP_classNames[i]);");
    out.println("                    return JNI_ERR;");
    out.println("                }");
    // cache here for custom class loaders
    out.println("                JavaCPP_classes[i] = cls == NULL ? NULL : (jclass)env->NewWeakGlobalRef(cls);");
    out.println("                if (env->ExceptionCheck()) {");
    out.println("                    JavaCPP_log(\"Error creating global reference of class %s.\", JavaCPP_classNames[i]);");
    out.println("                    return JNI_ERR;");
    out.println("                }");
    out.println("                env->PopLocalFrame(NULL);");
    out.println("            }");
    out.println("        }");
    out.println("    }");
    out.println("    JavaCPP_addressFID = JavaCPP_getFieldID(env, " + jclasses.index(Pointer.class) + ", \"address\", \"J\");");
    out.println("    if (JavaCPP_addressFID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    JavaCPP_positionFID = JavaCPP_getFieldID(env, " + jclasses.index(Pointer.class) + ", \"position\", \"J\");");
    out.println("    if (JavaCPP_positionFID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    JavaCPP_limitFID = JavaCPP_getFieldID(env, " + jclasses.index(Pointer.class) + ", \"limit\", \"J\");");
    out.println("    if (JavaCPP_limitFID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    JavaCPP_capacityFID = JavaCPP_getFieldID(env, " + jclasses.index(Pointer.class) + ", \"capacity\", \"J\");");
    out.println("    if (JavaCPP_capacityFID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    JavaCPP_deallocatorFID = JavaCPP_getFieldID(env, " + jclasses.index(Pointer.class) + ", \"deallocator\", \"" + signature(deallocator) + "\");");
    out.println("    if (JavaCPP_deallocatorFID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    JavaCPP_ownerAddressFID = JavaCPP_getFieldID(env, " + jclasses.index(nativeDeallocator) + ", \"ownerAddress\", \"J\");");
    out.println("    if (JavaCPP_ownerAddressFID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    if (declareEnums) {
        out.println("    JavaCPP_byteValueFID = JavaCPP_getFieldID(env, \"" + ByteEnum.class.getName().replace('.', '/') + "\", \"value\", \"B\");");
        out.println("    if (JavaCPP_byteValueFID == NULL) {");
        out.println("        return JNI_ERR;");
        out.println("    }");
        out.println("    JavaCPP_shortValueFID = JavaCPP_getFieldID(env, \"" + ShortEnum.class.getName().replace('.', '/') + "\", \"value\", \"S\");");
        out.println("    if (JavaCPP_shortValueFID == NULL) {");
        out.println("        return JNI_ERR;");
        out.println("    }");
        out.println("    JavaCPP_intValueFID = JavaCPP_getFieldID(env, \"" + IntEnum.class.getName().replace('.', '/') + "\", \"value\", \"I\");");
        out.println("    if (JavaCPP_intValueFID == NULL) {");
        out.println("        return JNI_ERR;");
        out.println("    }");
        out.println("    JavaCPP_longValueFID = JavaCPP_getFieldID(env, \"" + LongEnum.class.getName().replace('.', '/') + "\", \"value\", \"J\");");
        out.println("    if (JavaCPP_longValueFID == NULL) {");
        out.println("        return JNI_ERR;");
        out.println("    }");
    }
    out.println("    JavaCPP_initMID = JavaCPP_getMethodID(env, " + jclasses.index(Pointer.class) + ", \"init\", \"(JJJJ)V\");");
    out.println("    if (JavaCPP_initMID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    JavaCPP_arrayMID = JavaCPP_getMethodID(env, " + jclasses.index(Buffer.class) + ", \"array\", \"()Ljava/lang/Object;\");");
    out.println("    if (JavaCPP_arrayMID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    JavaCPP_stringMID = JavaCPP_getMethodID(env, " + jclasses.index(String.class) + ", \"<init>\", \"([B)V\");");
    out.println("    if (JavaCPP_stringMID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    JavaCPP_getBytesMID = JavaCPP_getMethodID(env, " + jclasses.index(String.class) + ", \"getBytes\", \"()[B\");");
    out.println("    if (JavaCPP_getBytesMID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    JavaCPP_toStringMID = JavaCPP_getMethodID(env, " + jclasses.index(Object.class) + ", \"toString\", \"()Ljava/lang/String;\");");
    out.println("    if (JavaCPP_toStringMID == NULL) {");
    out.println("        return JNI_ERR;");
    out.println("    }");
    out.println("    return env->GetVersion();");
    out.println("}");
    out.println();
    if (out2 != null) {
        out2.println("JNIIMPORT int JavaCPP_uninit" + loadSuffix + "();");
        out2.println();
        out.println("JNIEXPORT int JavaCPP_uninit" + loadSuffix + "() {");
        out.println("#if defined(__ANDROID__) || TARGET_OS_IPHONE");
        out.println("    return JNI_OK;");
        out.println("#else");
        out.println("    JavaVM *vm = JavaCPP_vm;");
        out.println("    JNI_OnUnload" + loadSuffix + "(JavaCPP_vm, NULL);");
        out.println("    return vm->DestroyJavaVM();");
        out.println("#endif");
        out.println("}");
    }
    out.println();
    out.println("JNIEXPORT void JNICALL JNI_OnUnload" + loadSuffix + "(JavaVM* vm, void* reserved) {");
    out.println("    JNIEnv* env;");
    out.println("    if (vm->GetEnv((void**)&env, " + JNI_VERSION + ") != JNI_OK) {");
    out.println("        JavaCPP_log(\"Could not get JNIEnv for " + JNI_VERSION + " inside JNI_OnUnLoad" + loadSuffix + "().\");");
    out.println("        return;");
    out.println("    }");
    out.println("    for (int i = 0; i < " + jclasses.size() + "; i++) {");
    out.println("        env->DeleteWeakGlobalRef((jweak)JavaCPP_classes[i]);");
    out.println("        JavaCPP_classes[i] = NULL;");
    out.println("    }");
    if (baseLoadSuffix != null && !baseLoadSuffix.isEmpty()) {
        out.println("    JNI_OnUnload" + baseLoadSuffix + "(vm, reserved);");
    }
    out.println("    JavaCPP_vm = NULL;");
    out.println("}");
    out.println();
    boolean supportedPlatform = false;
    LinkedHashSet<Class> allClasses = new LinkedHashSet<Class>();
    if (baseLoadSuffix == null || baseLoadSuffix.isEmpty()) {
        supportedPlatform = true;
        allClasses.addAll(baseClasses);
    }
    if (classes != null) {
        allClasses.addAll(Arrays.asList(classes));
        for (Class<?> cls : classes) {
            supportedPlatform |= Loader.checkPlatform(cls, properties);
        }
    }
    boolean didSomethingUseful = false;
    for (Class<?> cls : allClasses) {
        try {
            didSomethingUseful |= methods(cls);
        } catch (NoClassDefFoundError e) {
            logger.warn("Could not generate code for class " + cls.getCanonicalName() + ": " + e);
        }
    }
    out.println("}");
    out.println();
    if (out2 != null) {
        out2.println("#ifdef __cplusplus");
        out2.println("}");
        out2.println("#endif");
    }
    return supportedPlatform;
}
Also used : FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) IntBuffer(java.nio.IntBuffer) CharBuffer(java.nio.CharBuffer) ShortBuffer(java.nio.ShortBuffer) Buffer(java.nio.Buffer) DoubleBuffer(java.nio.DoubleBuffer) LongBuffer(java.nio.LongBuffer) LinkedHashSet(java.util.LinkedHashSet) ClassProperties(org.bytedeco.javacpp.ClassProperties) Loader(org.bytedeco.javacpp.Loader) CLongPointer(org.bytedeco.javacpp.CLongPointer) CharPointer(org.bytedeco.javacpp.CharPointer) IntPointer(org.bytedeco.javacpp.IntPointer) BytePointer(org.bytedeco.javacpp.BytePointer) PointerPointer(org.bytedeco.javacpp.PointerPointer) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) LongPointer(org.bytedeco.javacpp.LongPointer) ShortPointer(org.bytedeco.javacpp.ShortPointer) BoolPointer(org.bytedeco.javacpp.BoolPointer) DoublePointer(org.bytedeco.javacpp.DoublePointer) FloatPointer(org.bytedeco.javacpp.FloatPointer) Pointer(org.bytedeco.javacpp.Pointer) SizeTPointer(org.bytedeco.javacpp.SizeTPointer) List(java.util.List)

Example 63 with Pointer

use of org.bytedeco.javacpp.Pointer in project javacpp by bytedeco.

the class Generator method callback.

void callback(Class<?> cls, Method callbackMethod, String callbackName, boolean needDefinition, MethodInformation methodInfo) {
    Class<?> callbackReturnType = callbackMethod.getReturnType();
    Class<?>[] callbackParameterTypes = callbackMethod.getParameterTypes();
    Annotation[] callbackAnnotations = callbackMethod.getAnnotations();
    Annotation[][] callbackParameterAnnotations = callbackMethod.getParameterAnnotations();
    String instanceTypeName = functionClassName(cls);
    String[] callbackTypeName = cppFunctionTypeName(callbackMethod);
    String[] returnConvention = callbackTypeName[0].split("\\(");
    returnConvention[1] = constValueTypeName(returnConvention[1]);
    String parameterDeclaration = callbackTypeName[1].substring(1);
    String fieldName = mangle(callbackMethod.getName()) + "__" + mangle(signature(callbackMethod.getParameterTypes()));
    String firstLine = "";
    if (methodInfo != null) {
        // stuff from a virtualized class
        String nonconstParamDeclaration = parameterDeclaration.endsWith(" const") ? parameterDeclaration.substring(0, parameterDeclaration.length() - 6) : parameterDeclaration;
        String[] typeName = methodInfo.returnRaw ? new String[] { "" } : cppTypeName(methodInfo.cls);
        String valueTypeName = valueTypeName(typeName);
        String subType = "JavaCPP_" + mangle(valueTypeName);
        Set<String> memberList = virtualMembers.get(cls);
        if (memberList == null) {
            virtualMembers.put(cls, memberList = new LinkedHashSet<String>());
        }
        String member = "    ";
        if (methodInfo.arrayAllocator) {
            return;
        } else if (methodInfo.allocator) {
            member += subType + nonconstParamDeclaration + " : " + valueTypeName + "(";
            for (int j = 0; j < callbackParameterTypes.length; j++) {
                member += "arg" + j;
                if (j < callbackParameterTypes.length - 1) {
                    member += ", ";
                }
            }
            member += "), obj(NULL) { }";
        } else {
            Set<String> functionList = virtualFunctions.get(cls);
            if (functionList == null) {
                virtualFunctions.put(cls, functionList = new LinkedHashSet<String>());
            }
            String usingLine = "using " + valueTypeName + "::" + methodInfo.memberName[0] + ";";
            boolean needUsing = true;
            for (String s : memberList) {
                if (s.split("\n", 2)[0].equals(member + usingLine)) {
                    needUsing = false;
                    break;
                }
            }
            if (needUsing) {
                member += usingLine + "\n    ";
            }
            member += "virtual " + returnConvention[0] + (returnConvention.length > 1 ? returnConvention[1] : "") + methodInfo.memberName[0] + parameterDeclaration + ";\n    " + returnConvention[0] + "super_" + methodInfo.memberName[0] + nonconstParamDeclaration + " { ";
            if (methodInfo.method.getAnnotation(Virtual.class).value()) {
                member += "throw JavaCPP_exception(\"Cannot call a pure virtual function.\"); }";
            } else {
                member += (callbackReturnType != void.class ? "return " : "") + valueTypeName + "::" + methodInfo.memberName[0] + "(";
                for (int j = 0; j < callbackParameterTypes.length; j++) {
                    member += "arg" + j;
                    if (j < callbackParameterTypes.length - 1) {
                        member += ", ";
                    }
                }
                member += "); }";
            }
            firstLine = returnConvention[0] + (returnConvention.length > 1 ? returnConvention[1] : "") + subType + "::" + methodInfo.memberName[0] + parameterDeclaration + " {";
            functionList.add(fieldName);
        }
        memberList.add(member);
    } else if (callbackName != null) {
        callbacks.index("static " + instanceTypeName + " " + callbackName + "_instance;");
        Convention convention = cls.getAnnotation(Convention.class);
        if (convention != null && !convention.extern().equals("C")) {
            out.println("extern \"" + convention.extern() + "\" {");
            if (out2 != null) {
                out2.println("extern \"" + convention.extern() + "\" {");
            }
        }
        if (out2 != null) {
            out2.println("JNIIMPORT " + returnConvention[0] + (returnConvention.length > 1 ? returnConvention[1] : "") + callbackName + parameterDeclaration + ";");
        }
        out.println("JNIEXPORT " + returnConvention[0] + (returnConvention.length > 1 ? returnConvention[1] : "") + callbackName + parameterDeclaration + " {");
        out.print((callbackReturnType != void.class ? "    return " : "    ") + callbackName + "_instance(");
        for (int j = 0; j < callbackParameterTypes.length; j++) {
            out.print("arg" + j);
            if (j < callbackParameterTypes.length - 1) {
                out.print(", ");
            }
        }
        out.println(");");
        out.println("}");
        if (convention != null && !convention.extern().equals("C")) {
            out.println("}");
            if (out2 != null) {
                out2.println("}");
            }
        }
        firstLine = returnConvention[0] + instanceTypeName + "::operator()" + parameterDeclaration + " {";
    }
    if (!needDefinition) {
        return;
    }
    out.println(firstLine);
    String returnPrefix = "";
    if (callbackReturnType != void.class) {
        out.println("    " + jniTypeName(callbackReturnType) + " rarg = 0;");
        returnPrefix = "rarg = ";
        if (callbackReturnType == String.class) {
            returnPrefix += "(jstring)";
        }
    }
    String callbackReturnCast = cast(callbackReturnType, callbackAnnotations);
    Annotation returnBy = by(callbackAnnotations);
    String[] returnTypeName = cppTypeName(callbackReturnType);
    String returnValueTypeName = valueTypeName(returnTypeName);
    AdapterInformation returnAdapterInfo = adapterInformation(false, returnValueTypeName, callbackAnnotations);
    out.println("    jthrowable exc = NULL;");
    out.println("    JNIEnv* env;");
    out.println("    bool attached = JavaCPP_getEnv(&env);");
    out.println("    if (env == NULL) {");
    out.println("        goto end;");
    out.println("    }");
    out.println("{");
    if (callbackParameterTypes.length > 0) {
        out.println("    jvalue args[" + callbackParameterTypes.length + "];");
        for (int j = 0; j < callbackParameterTypes.length; j++) {
            if (callbackParameterTypes[j].isPrimitive()) {
                out.println("    args[" + j + "]." + signature(callbackParameterTypes[j]).toLowerCase() + " = (" + jniTypeName(callbackParameterTypes[j]) + ")arg" + j + ";");
            } else if (Enum.class.isAssignableFrom(callbackParameterTypes[j])) {
                accessesEnums = true;
                String s = enumValueType(callbackParameterTypes[j]);
                if (s != null) {
                    String S = Character.toUpperCase(s.charAt(0)) + s.substring(1);
                    out.println("    jobject obj" + j + " = JavaCPP_createPointer(env, " + jclasses.index(callbackParameterTypes[j]) + ");");
                    out.println("    args[" + j + "].l = obj" + j + ";");
                    out.println("    if (obj" + j + " != NULL) {");
                    out.println("        env->Set" + S + "Field(obj" + j + ", JavaCPP_" + s + "ValueFID, (j" + s + ")arg" + j + ");");
                    out.println("    }");
                }
            } else {
                Annotation passBy = by(callbackParameterAnnotations[j]);
                String[] typeName = cppTypeName(callbackParameterTypes[j]);
                String valueTypeName = valueTypeName(typeName);
                AdapterInformation adapterInfo = adapterInformation(false, valueTypeName, callbackParameterAnnotations[j]);
                if (adapterInfo != null) {
                    usesAdapters = true;
                    out.println("    " + adapterInfo.name + " adapter" + j + "(arg" + j + ");");
                }
                if (Pointer.class.isAssignableFrom(callbackParameterTypes[j]) || Buffer.class.isAssignableFrom(callbackParameterTypes[j]) || (callbackParameterTypes[j].isArray() && callbackParameterTypes[j].getComponentType().isPrimitive())) {
                    String cast = "(" + typeName[0] + typeName[1] + ")";
                    if (FunctionPointer.class.isAssignableFrom(callbackParameterTypes[j])) {
                        functions.index(callbackParameterTypes[j]);
                        typeName[0] = functionClassName(callbackParameterTypes[j]) + "*";
                        typeName[1] = "";
                        valueTypeName = valueTypeName(typeName);
                    } else if (virtualFunctions.containsKey(callbackParameterTypes[j])) {
                        String subType = "JavaCPP_" + mangle(valueTypeName);
                        valueTypeName = subType;
                    }
                    out.println("    " + jniTypeName(callbackParameterTypes[j]) + " obj" + j + " = NULL;");
                    out.println("    " + typeName[0] + " ptr" + j + typeName[1] + " = NULL;");
                    if (FunctionPointer.class.isAssignableFrom(callbackParameterTypes[j])) {
                        out.println("    ptr" + j + " = new (std::nothrow) " + valueTypeName + ";");
                        out.println("    if (ptr" + j + " != NULL) {");
                        out.println("        ptr" + j + "->ptr = " + cast + "&arg" + j + ";");
                        out.println("    }");
                    } else if (adapterInfo != null) {
                        out.println("    ptr" + j + " = adapter" + j + ";");
                    } else if (passBy instanceof ByVal && callbackParameterTypes[j] != Pointer.class) {
                        out.println("    ptr" + j + (noException(callbackParameterTypes[j], callbackMethod) ? " = new (std::nothrow) " : " = new ") + valueTypeName + typeName[1] + "(*" + cast + "&arg" + j + ");");
                    } else if (passBy instanceof ByVal || passBy instanceof ByRef) {
                        out.println("    ptr" + j + " = " + cast + "&arg" + j + ";");
                    } else if (passBy instanceof ByPtrPtr) {
                        out.println("    if (arg" + j + " == NULL) {");
                        out.println("        JavaCPP_log(\"Pointer address of argument " + j + " is NULL in callback for " + cls.getCanonicalName() + ".\");");
                        out.println("    } else {");
                        out.println("        ptr" + j + " = " + cast + "*arg" + j + ";");
                        out.println("    }");
                    } else {
                        // ByPtr || ByPtrRef
                        out.println("    ptr" + j + " = " + cast + "arg" + j + ";");
                    }
                }
                boolean needInit = false;
                if (adapterInfo != null) {
                    if (callbackParameterTypes[j] != String.class) {
                        out.println("    jlong size" + j + " = (jlong)adapter" + j + ".size;");
                        out.println("    void* owner" + j + " = adapter" + j + ".owner;");
                        out.println("    void (*deallocator" + j + ")(void*) = &" + adapterInfo.name + "::deallocate;");
                    }
                    needInit = true;
                } else if ((passBy instanceof ByVal && callbackParameterTypes[j] != Pointer.class) || FunctionPointer.class.isAssignableFrom(callbackParameterTypes[j])) {
                    out.println("    jlong size" + j + " = 1;");
                    out.println("    void* owner" + j + " = ptr" + j + ";");
                    out.println("    void (*deallocator" + j + ")(void*) = &JavaCPP_" + mangle(callbackParameterTypes[j].getName()) + "_deallocate;");
                    deallocators.index(callbackParameterTypes[j]);
                    needInit = true;
                }
                if (Pointer.class.isAssignableFrom(callbackParameterTypes[j])) {
                    String s = "    obj" + j + " = JavaCPP_createPointer(env, " + jclasses.index(callbackParameterTypes[j]) + ");";
                    adapterInfo = adapterInformation(true, valueTypeName, callbackParameterAnnotations[j]);
                    if (adapterInfo != null || passBy instanceof ByPtrPtr || passBy instanceof ByPtrRef) {
                        out.println(s);
                    } else {
                        out.println("    if (ptr" + j + " != NULL) { ");
                        out.println("    " + s);
                        out.println("    }");
                    }
                    out.println("    if (obj" + j + " != NULL) { ");
                    if (needInit) {
                        out.println("        JavaCPP_initPointer(env, obj" + j + ", ptr" + j + ", size" + j + ", owner" + j + ", deallocator" + j + ");");
                    } else {
                        out.println("        env->SetLongField(obj" + j + ", JavaCPP_addressFID, ptr_to_jlong(ptr" + j + "));");
                    }
                    out.println("    }");
                    out.println("    args[" + j + "].l = obj" + j + ";");
                } else if (callbackParameterTypes[j] == String.class) {
                    passesStrings = true;
                    out.println("    jstring obj" + j + " = JavaCPP_createString(env, (const char*)" + (adapterInfo != null ? "adapter" : "arg") + j + ");");
                    out.println("    args[" + j + "].l = obj" + j + ";");
                } else if (callbackParameterTypes[j].isArray() && callbackParameterTypes[j].getComponentType().isPrimitive()) {
                    if (adapterInfo == null) {
                        out.println("    jlong size" + j + " = ptr" + j + " != NULL ? 1 : 0;");
                    }
                    String componentType = callbackParameterTypes[j].getComponentType().getName();
                    String S = Character.toUpperCase(componentType.charAt(0)) + componentType.substring(1);
                    out.println("    if (ptr" + j + " != NULL) {");
                    out.println("        obj" + j + " = env->New" + S + "Array(size" + j + " < INT_MAX ? size" + j + " : INT_MAX);");
                    out.println("        env->Set" + S + "ArrayRegion(obj" + j + ", 0, size" + j + " < INT_MAX ? size" + j + " : INT_MAX, (j" + componentType + "*)ptr" + j + ");");
                    out.println("    }");
                    if (adapterInfo != null) {
                        out.println("    if (deallocator" + j + " != 0 && ptr" + j + " != NULL) {");
                        out.println("        (*(void(*)(void*))jlong_to_ptr(deallocator" + j + "))((void*)ptr" + j + ");");
                        out.println("    }");
                    }
                } else if (Buffer.class.isAssignableFrom(callbackParameterTypes[j])) {
                    if (adapterInfo == null) {
                        out.println("    jlong size" + j + " = ptr" + j + " != NULL ? 1 : 0;");
                    }
                    out.println("    if (ptr" + j + " != NULL) {");
                    out.println("        jlong sizeptr = size" + j + " * sizeof(ptr" + j + "[0]);");
                    out.println("        obj" + j + " = env->NewDirectByteBuffer((void*)ptr" + j + ", sizeptr < INT_MAX ? sizeptr : INT_MAX);");
                    out.println("    }");
                } else {
                    logger.warn("Callback \"" + callbackMethod + "\" has unsupported parameter type \"" + callbackParameterTypes[j].getCanonicalName() + "\". Compilation will most likely fail.");
                }
            }
        }
    }
    if (methodInfo != null) {
        out.println("    if (" + fieldName + " == NULL) {");
        out.println("        " + fieldName + " = JavaCPP_getMethodID(env, " + jclasses.index(cls) + ", \"" + methodInfo.method.getName() + "\", \"(" + signature(methodInfo.method.getParameterTypes()) + ")" + signature(methodInfo.method.getReturnType()) + "\");");
        out.println("    }");
        out.println("    jmethodID mid = " + fieldName + ";");
    } else if (callbackName != null) {
        out.println("    if (obj == NULL) {");
        out.println("        obj = JavaCPP_createPointer(env, " + jclasses.index(cls) + ");");
        out.println("        obj = obj == NULL ? NULL : env->NewGlobalRef(obj);");
        out.println("        if (obj == NULL) {");
        out.println("            JavaCPP_log(\"Error creating global reference of " + cls.getCanonicalName() + " instance for callback.\");");
        out.println("        } else {");
        out.println("            env->SetLongField(obj, JavaCPP_addressFID, ptr_to_jlong(this));");
        out.println("        }");
        out.println("        ptr = &" + callbackName + ";");
        out.println("    }");
        out.println("    if (mid == NULL) {");
        out.println("        mid = JavaCPP_getMethodID(env, " + jclasses.index(cls) + ", \"" + callbackMethod.getName() + "\", \"(" + signature(callbackMethod.getParameterTypes()) + ")" + signature(callbackMethod.getReturnType()) + "\");");
        out.println("    }");
    }
    out.println("    if (env->IsSameObject(obj, NULL)) {");
    out.println("        JavaCPP_log(\"Function pointer object is NULL in callback for " + cls.getCanonicalName() + ".\");");
    out.println("    } else if (mid == NULL) {");
    out.println("        JavaCPP_log(\"Error getting method ID of function caller \\\"" + callbackMethod + "\\\" for callback.\");");
    out.println("    } else {");
    String s = "Object";
    if (callbackReturnType.isPrimitive()) {
        s = callbackReturnType.getName();
        s = Character.toUpperCase(s.charAt(0)) + s.substring(1);
    }
    out.println("        " + returnPrefix + "env->Call" + s + "MethodA(obj, mid, " + (callbackParameterTypes.length == 0 ? "NULL);" : "args);"));
    out.println("        if ((exc = env->ExceptionOccurred()) != NULL) {");
    out.println("            env->ExceptionClear();");
    out.println("        }");
    out.println("    }");
    for (int j = 0; j < callbackParameterTypes.length; j++) {
        if (Pointer.class.isAssignableFrom(callbackParameterTypes[j])) {
            String[] typeName = cppTypeName(callbackParameterTypes[j]);
            Annotation passBy = by(callbackParameterAnnotations[j]);
            String cast = cast(callbackParameterTypes[j], callbackParameterAnnotations[j]);
            String valueTypeName = valueTypeName(typeName);
            AdapterInformation adapterInfo = adapterInformation(true, valueTypeName, callbackParameterAnnotations[j]);
            if ("void*".equals(typeName[0]) && !callbackParameterTypes[j].isAnnotationPresent(Opaque.class)) {
                typeName[0] = "char*";
            }
            if (adapterInfo != null || passBy instanceof ByPtrPtr || passBy instanceof ByPtrRef) {
                out.println("    " + typeName[0] + " rptr" + j + typeName[1] + " = (" + typeName[0] + typeName[1] + ")jlong_to_ptr(env->GetLongField(obj" + j + ", JavaCPP_addressFID));");
                if (adapterInfo != null) {
                    out.println("    jlong rsize" + j + " = env->GetLongField(obj" + j + ", JavaCPP_limitFID);");
                    out.println("    void* rowner" + j + " = JavaCPP_getPointerOwner(env, obj" + j + ");");
                }
                if (!callbackParameterTypes[j].isAnnotationPresent(Opaque.class)) {
                    out.println("    jlong rposition" + j + " = env->GetLongField(obj" + j + ", JavaCPP_positionFID);");
                    out.println("    rptr" + j + " += rposition" + j + ";");
                    if (adapterInfo != null) {
                        out.println("    rsize" + j + " -= rposition" + j + ";");
                    }
                }
                if (adapterInfo != null) {
                    out.println("    adapter" + j + ".assign(rptr" + j + ", rsize" + j + ", rowner" + j + ");");
                } else if (passBy instanceof ByPtrPtr) {
                    out.println("    if (arg" + j + " != NULL) {");
                    out.println("        *arg" + j + " = *" + cast + "&rptr" + j + ";");
                    out.println("    }");
                } else if (passBy instanceof ByPtrRef) {
                    out.println("    arg" + j + " = " + cast + "rptr" + j + ";");
                }
            }
        }
        if (!callbackParameterTypes[j].isPrimitive()) {
            out.println("    env->DeleteLocalRef(obj" + j + ");");
        }
    }
    out.println("}");
    out.println("end:");
    if (callbackReturnType != void.class) {
        if ("void*".equals(returnTypeName[0]) && !callbackReturnType.isAnnotationPresent(Opaque.class)) {
            returnTypeName[0] = "char*";
        }
        if (Enum.class.isAssignableFrom(callbackReturnType)) {
            accessesEnums = true;
            s = enumValueType(callbackReturnType);
            if (s != null) {
                String S = Character.toUpperCase(s.charAt(0)) + s.substring(1);
                out.println("    if (rarg == NULL) {");
                out.println("        JavaCPP_log(\"Enum for return is NULL in callback for " + cls.getCanonicalName() + ".\");");
                out.println("    }");
                out.println("    " + returnTypeName[0] + " rval" + returnTypeName[1] + " = (" + returnTypeName[0] + returnTypeName[1] + ")(rarg == NULL ? 0 : env->Get" + S + "Field(rarg, JavaCPP_" + s + "ValueFID));");
            }
        } else if (Pointer.class.isAssignableFrom(callbackReturnType)) {
            out.println("    " + returnTypeName[0] + " rptr" + returnTypeName[1] + " = rarg == NULL ? NULL : (" + returnTypeName[0] + returnTypeName[1] + ")jlong_to_ptr(env->GetLongField(rarg, JavaCPP_addressFID));");
            if (returnAdapterInfo != null) {
                out.println("    jlong rsize = rarg == NULL ? 0 : env->GetLongField(rarg, JavaCPP_limitFID);");
                out.println("    void* rowner = JavaCPP_getPointerOwner(env, rarg);");
            }
            if (!callbackReturnType.isAnnotationPresent(Opaque.class)) {
                out.println("    jlong rposition = rarg == NULL ? 0 : env->GetLongField(rarg, JavaCPP_positionFID);");
                out.println("    rptr += rposition;");
                if (returnAdapterInfo != null) {
                    out.println("    rsize -= rposition;");
                }
            }
        } else if (callbackReturnType == String.class) {
            passesStrings = true;
            out.println("    " + returnTypeName[0] + " rptr" + returnTypeName[1] + " = JavaCPP_getStringBytes(env, rarg);");
            if (returnAdapterInfo != null) {
                out.println("    jlong rsize = 0;");
                out.println("    void* rowner = (void*)rptr");
            }
        } else if (Buffer.class.isAssignableFrom(callbackReturnType)) {
            out.println("    " + returnTypeName[0] + " rptr" + returnTypeName[1] + " = rarg == NULL ? NULL : env->GetDirectBufferAddress(rarg);");
            if (returnAdapterInfo != null) {
                out.println("    jlong rsize = rarg == NULL ? 0 : env->GetDirectBufferCapacity(rarg);");
                out.println("    void* rowner = (void*)rptr;");
            }
        } else if (!callbackReturnType.isPrimitive()) {
            logger.warn("Callback \"" + callbackMethod + "\" has unsupported return type \"" + callbackReturnType.getCanonicalName() + "\". Compilation will most likely fail.");
        }
    }
    passesStrings = true;
    out.println("    if (exc != NULL) {");
    out.println("        jstring str = (jstring)env->CallObjectMethod(exc, JavaCPP_toStringMID);");
    out.println("        env->DeleteLocalRef(exc);");
    out.println("        const char *msg = JavaCPP_getStringBytes(env, str);");
    out.println("        JavaCPP_exception e(msg);");
    out.println("        JavaCPP_releaseStringBytes(env, str, msg);");
    out.println("        env->DeleteLocalRef(str);");
    out.println("        JavaCPP_detach(attached);");
    out.println("        throw e;");
    out.println("    } else {");
    out.println("        JavaCPP_detach(attached);");
    out.println("    }");
    if (callbackReturnType != void.class) {
        if (callbackReturnType.isPrimitive()) {
            out.println("    return " + callbackReturnCast + "rarg;");
        } else if (Enum.class.isAssignableFrom(callbackReturnType)) {
            out.println("    return " + callbackReturnCast + "rval;");
        } else if (returnAdapterInfo != null) {
            usesAdapters = true;
            out.println("    return " + returnAdapterInfo.name + "(" + callbackReturnCast + "rptr, rsize, rowner);");
        } else if (FunctionPointer.class.isAssignableFrom(callbackReturnType)) {
            functions.index(callbackReturnType);
            out.println("    return " + callbackReturnCast + "(rptr == NULL ? NULL : rptr->ptr);");
        } else if (returnBy instanceof ByVal || returnBy instanceof ByRef) {
            out.println("    if (rptr == NULL) {");
            out.println("        JavaCPP_log(\"Return pointer address is NULL in callback for " + cls.getCanonicalName() + ".\");");
            out.println("        static " + returnConvention[0] + " empty" + returnTypeName[1] + ";");
            out.println("        return empty;");
            out.println("    } else {");
            out.println("        return *" + callbackReturnCast + "rptr;");
            out.println("    }");
        } else if (returnBy instanceof ByPtrPtr) {
            out.println("    return " + callbackReturnCast + "&rptr;");
        } else {
            // ByPtr || ByPtrRef
            out.println("    return " + callbackReturnCast + "rptr;");
        }
    }
    out.println("}");
}
Also used : LinkedHashSet(java.util.LinkedHashSet) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) IntBuffer(java.nio.IntBuffer) CharBuffer(java.nio.CharBuffer) ShortBuffer(java.nio.ShortBuffer) Buffer(java.nio.Buffer) DoubleBuffer(java.nio.DoubleBuffer) LongBuffer(java.nio.LongBuffer) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) ByRef(org.bytedeco.javacpp.annotation.ByRef) ByPtrRef(org.bytedeco.javacpp.annotation.ByPtrRef) Opaque(org.bytedeco.javacpp.annotation.Opaque) CLongPointer(org.bytedeco.javacpp.CLongPointer) CharPointer(org.bytedeco.javacpp.CharPointer) IntPointer(org.bytedeco.javacpp.IntPointer) BytePointer(org.bytedeco.javacpp.BytePointer) PointerPointer(org.bytedeco.javacpp.PointerPointer) FunctionPointer(org.bytedeco.javacpp.FunctionPointer) LongPointer(org.bytedeco.javacpp.LongPointer) ShortPointer(org.bytedeco.javacpp.ShortPointer) BoolPointer(org.bytedeco.javacpp.BoolPointer) DoublePointer(org.bytedeco.javacpp.DoublePointer) FloatPointer(org.bytedeco.javacpp.FloatPointer) Pointer(org.bytedeco.javacpp.Pointer) SizeTPointer(org.bytedeco.javacpp.SizeTPointer) ByPtrPtr(org.bytedeco.javacpp.annotation.ByPtrPtr) Annotation(java.lang.annotation.Annotation) ByVal(org.bytedeco.javacpp.annotation.ByVal) Convention(org.bytedeco.javacpp.annotation.Convention)

Example 64 with Pointer

use of org.bytedeco.javacpp.Pointer in project javacv by bytedeco.

the class OpenKinect2FrameGrabber method grabDepth.

protected void grabDepth() {
    /**
     * 512x424 float also ?.
     */
    org.bytedeco.libfreenect2.Frame depthImage = frames.get(org.bytedeco.libfreenect2.Frame.Depth);
    int channels = 1;
    int iplDepth = IPL_DEPTH_32F;
    int bpp = (int) depthImage.bytes_per_pixel();
    int deviceWidth = (int) depthImage.width();
    int deviceHeight = (int) depthImage.height();
    Pointer rawDepthData = depthImage.data();
    if (rawDepthImage == null) {
        rawDepthImage = IplImage.createHeader(deviceWidth, deviceHeight, iplDepth, channels);
    }
    cvSetData(rawDepthImage, rawDepthData, deviceWidth * channels * iplDepth / 8);
}
Also used : Pointer(org.bytedeco.javacpp.Pointer) BytePointer(org.bytedeco.javacpp.BytePointer) org.bytedeco.libfreenect2(org.bytedeco.libfreenect2)

Example 65 with Pointer

use of org.bytedeco.javacpp.Pointer in project javacv by bytedeco.

the class RealSense2FrameGrabber method getFrameData.

private Pointer getFrameData(rs2_frame frame) throws Exception {
    Pointer frameData = rs2_get_frame_data(frame, error);
    checkError(error);
    return frameData;
}
Also used : Pointer(org.bytedeco.javacpp.Pointer) IntPointer(org.bytedeco.javacpp.IntPointer)

Aggregations

Pointer (org.bytedeco.javacpp.Pointer)68 FloatPointer (org.bytedeco.javacpp.FloatPointer)33 DoublePointer (org.bytedeco.javacpp.DoublePointer)31 IntPointer (org.bytedeco.javacpp.IntPointer)29 BytePointer (org.bytedeco.javacpp.BytePointer)23 CudaContext (org.nd4j.linalg.jcublas.context.CudaContext)23 INDArray (org.nd4j.linalg.api.ndarray.INDArray)21 ShortPointer (org.bytedeco.javacpp.ShortPointer)20 CudaPointer (org.nd4j.jita.allocator.pointers.CudaPointer)19 DataBuffer (org.nd4j.linalg.api.buffer.DataBuffer)18 GridExecutioner (org.nd4j.linalg.api.ops.executioner.GridExecutioner)16 ByteBuffer (java.nio.ByteBuffer)13 PointerPointer (org.bytedeco.javacpp.PointerPointer)12 LongPointer (org.bytedeco.javacpp.LongPointer)10 CUstream_st (org.bytedeco.javacpp.cuda.CUstream_st)10 org.nd4j.jita.allocator.pointers.cuda.cusolverDnHandle_t (org.nd4j.jita.allocator.pointers.cuda.cusolverDnHandle_t)10 CublasPointer (org.nd4j.linalg.jcublas.CublasPointer)10 FunctionPointer (org.bytedeco.javacpp.FunctionPointer)9 BoolPointer (org.bytedeco.javacpp.BoolPointer)8 CLongPointer (org.bytedeco.javacpp.CLongPointer)8