Передача параметров при вызове нативных функций с++ из андроида

В Qt Creator содан проект под андроид. Вот два файла с кодом:

c++

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include <QtAndroidExtras>

void pass_int(int value) {
    qDebug() << "pass_int: " << value;
}

void pass_double(double value1, double value2, double value3) {
    qDebug() << "pass_double: " << value1 << " : " << value2 << " : " << value3;
}

void test() {
    JNINativeMethod methods[] {
        {"pass_int", "(I)V", reinterpret_cast<void*>(&pass_int)},
        {"pass_double", "(DDD)V", reinterpret_cast<void*>(&pass_double)},
    };

    QAndroidJniObject java_class("ptz.andk.Jmain");
    QAndroidJniEnvironment env;
    jclass obj = env->GetObjectClass(java_class.object<jobject>());
    env->RegisterNatives(obj, methods, 2);
    env->DeleteLocalRef(obj);

    QAndroidJniObject::callStaticMethod<void>(
        "ptz/andk/Jmain",
        "test",
        "()V",
        QtAndroid::androidActivity().object());
}

int main(int argc, char *argv[]) {
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
    &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    test();

    return app.exec();
}

и java

package com.andk;

public class Jmain {
    private static native void pass_int(int value);
    private static native void pass_double(double value1, double value2, double value3);

    public static void test() {
        pass_int(123);
        pass_double(1.23, 2.34, 3.45);
    }
}

В функции test регистрируются две нативные функции и вызывается java функция test, в которой просто вызывются зарегистрированные нативные функции.

Я ожидаю получить вывод:

pass_int:  123
pass_double:  1.23  :  2.34  :  3.45

Но при запуске на эмуляторе получается

pass_int:  44720832
pass_double:  1.23  :  2.34  :  3.45

а при запуске на реальном устройстве

pass_int:  -709912000
pass_double:  -8.06905e-10  :  1.23  :  2.34

Что я делаю не так?


Ответы (1 шт):

Автор решения: user7860670

Тут неправильная сигнатура экспортируемых jni функций. Первые два параметра должны быть указателями на рантайм и объектом-классом. Кроме того, функции должны быть объявлены как noexcept во избежание пробрасывания c++ исключения через границу языка.

void pass_int
(
    ::JNIEnv * const p_env
,   ::jclass const Jmain_class
,   ::jint const value
) noexcept
→ Ссылка