0

次のシグネチャを持つ C++ メソッドがあります。

int cppGetData(string& data);

Java メソッドから呼び出す必要があります。

バージョン I :

byte[] javaGetData();

ゼロ以外の戻りコードを返すnull場合、どちらが返されますか。cppGetData

私は次のように書く必要があることを理解しています:

JNIEXPORT jbyteArray JNICALL jniGetData(JNIEnv * env, jobject thisObj) 
(
  string data;
  if (cppGetData(data))
  {
    return NULL;
  }

  jbyteArray jData = env->NewByteArray(data.size());
  env->SetByteArrayRegion(jData, 0, data.size(), (jbyte *)data.c_str());

  return jData;
}

私の問題は、によって返されたステータスを失うことcppGetDataです。一方、Javaは参照渡しがないので戸惑います。byte[]整数ステータスを返すにはどうすればよいですか?

もちろん、次のようなラッパーを使用することもできます。

public class ByteArrayWrapper{
  public byte[] bytes;
}

そして javaGetData は次のようになります。

int javaGetData(ByteArrayWrapper wrapper);

これはひどいです。jniGetDataAPI署名とメソッドの複雑さの両方の観点から。

より良い方法はありますか?

4

2 に答える 2

2

あなたが持っているものに最も近いのは、

native static int cppGetData(ByteBuffer bb);

これは、ByteBuffer が byte[] のラッパーであることに比べてそれほど優れているわけではありませんが、組み込みクラスを使用してそれを実行します。制限として、基になる byte[] はサイズ変更できませんが、limit.

別のオプションは、使用することです

native static int cppGetData(byte[][] bytes)

これにより、別の byte[] を返すことができます。

または、あなたができる

int[] num = { 0 };

native static byte[] cppGetData(int[] num)

またはオブジェクトのフィールドを更新します

class CallsCppGetData {
    int num;
    byte[] bytes;

    native void cppGetData(); // sets this.num and this.bytes.
}

複数の値を返すための解決策は、オブジェクトを使用することです。

あなたのどちらか

  • メソッドを呼び出しているオブジェクトの複数のフィールドを更新します。
  • 複数のフィールドをラップするときにオブジェクトを返します。
  • 設定する可変オブジェクトを渡します。int[]たとえば、 1 つの要素を持つan を渡すことができます。

新しいクラスを作成するのはひどいものですが、結果が 1 つもないメソッドを持つことも同様です。;)

于 2012-11-21T18:23:29.567 に答える
0

オブジェクトを渡すことが非常に問題である場合、他の解決策は1つだけです。2つの別々のメソッドがあります

jint prepareData();
jbyteArray getData();

指定したように、最初のものがゼロを返した場合にのみ呼び出されます。もちろん、このソリューションは、C 側で呼び出し間で永続的なデータを保存する必要があるため、特にアトミックでもスレッドセーフでもありません。Java側の同期ブロックで両方のネイティブ呼び出しをラップしない限り。しかし、ユビキタスなフレームワークの多くは、他の関数呼び出しの後に共通の内部状態を報告するために、この手法を大胆に使用しています。Win32 APIGetLastErrorが思い浮かびますが、それはスレッドセーフです。

于 2012-11-21T22:10:22.033 に答える