0

私はQtにかなり慣れていないので、Android 開発をしようとしています。私は Qt で作業しており、QAndroidJNIEnvironmentを使用しています。コードでQMetaObject::invokeMethodは、QMainWindow ヘッダーでスロットを呼び出すために使用するネイティブ メソッドを実装しています。問題は、Java ファイルのネイティブ メソッドに Java 整数配列 (QAndroindJniObject が jintArray であると私が信じている同等の型) であるパラメーターがあることです。引数を解決するために Q_ARG(type, value ) マクロに配置する対応する c++/Qt 型が見つかりません。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);
4

1 に答える 1

1

JNI API に従って Java 配列にアクセスする必要があります。最も簡単なのは、データをQVector. Java 配列の有効期間は制御できないため、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;
}
于 2015-09-18T20:02:13.703 に答える