Метод QMetaObject InvokeMethod, передающий аргумент целочисленного массива
Я довольно новичок в Qt и пытаюсь заняться разработкой Android. Я работаю с Qt и использую QAndroidJNIEnvironment. В коде я реализую свой родной метод, используя QMetaObject::invokeMethod
вызвать слот в заголовке QMainWindow. Проблема в том, что нативный метод в java-файле имеет параметр, который является целочисленным массивом java (эквивалентный тип, который я считаю в QAndroindJniObject - это jintArray). Я не могу найти соответствующий тип C++/Qt для размещения в макросе Q_ARG(тип, значение) для разрешения аргумента. Пожалуйста, помогите мне понять, что я делаю неправильно, так как я думал, что тип, эквивалентный jintArray, был int [], но я получаю ошибку, когда использую это. Заранее спасибо за помощь.
onReceiveNativeMounted (JNIEnv * env, jobject obj,jint array_index,jintArray version)
{
QMetaObject::invokeMethod(&MainWindow::instance(), "onReceiveMounted"
, Qt::QueuedConnection, Q_ARG(int, array_index),Q_ARG(int[], version));
return array_index;
}
ошибка, которую я получаю, ниже:
error: no matching function for call to
'QArgument<int []>::QArgument(const char [6], _jarray*&)'
#define Q_ARG(type, data) QArgument<type >(#type, data)
^
В соответствии с запросом подпись функции Java ниже:
public static native int onReceiveNativeMounted(int array_index, int[] version);
1 ответ
Вам необходимо получить доступ к массивам Java в соответствии с API JNI. Самое простое, что нужно сделать - это преобразовать данные в QVector
, Вам необходимо скопировать массив Java, поскольку его время жизни не находится под вашим контролем (если только вы этого не хотите, но это делает жизнь намного сложнее, чем нужно).
QVector toQVector(JNIEnv * env, jintArray arr) {
auto len = (*env)->GetArrayLength(env, arr);
QVector result(len);
auto data = (*env)->GetIntArrayElements(env, arr, 0);
for (int i = 0; i < len; ++i)
result[i] = data[i];
(*env)->ReleaseIntArrayElements(env, arr, data, 0);
return result;
}
Это немного более эффективно выполнять вызов непосредственно из функтора, а не через invokeMethod
, Функтор может захватить вектор:
int onReceiveNativeMounted (JNIEnv * env, jobject obj, jint array_index, jintArray version)
{
auto window = &MainWindow::instance();
auto vector = toQVector(env, version);
QObject sig;
sig.connect(&sig, &QObject::destroyed, window, [=]{
window->onReceiveMounted(array_index, vector.data());
}, Qt::QueuedConnection);
return array_index;
}