我是 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);
答案 0 :(得分:1)
您需要根据JNI API访问java数组。最简单的方法是将数据转换为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;
}