2012-01-23 8 views
2

からデータをマーシャリングするための最速の方法は何ですか:Javaでは私は多くのデータ・フィールド(> 15)を含むCデータ構造を持っていると仮定しJNI

struct MyData 
{ 
    int x; 
    float y; 
    ... 
} 

、私はのMyDataへのポインタを格納することができますCのデータ構造の長い、およびアクセスメンバーとしてJNIを通じて呼び出す:

long mydata_p = MyDataJNI.alloc(); 

int x = MyDataJNI.getX(mydata_p); 
float y = MyDataJNI.getY(mydata_p); 
... 

をしかし、これらの関数の呼び出しは、(同等のC関数呼び出しのコストを10倍、100倍)ショッキングに高価です。これは、getX、getYなどの実装が次のように単純であっても当てはまります。

return ((MyData*)())->x 

Q1:JNIはなぜ高価ですか?関数ポインタの呼び出し以外に何が起こっていますか? (参考のために、私はJNIで探していますアンドロイドで呼び出します。)

Q2:Javaの層で私のC構造体の要素のすべてが利用できるようにするために何を最速は何ですか?代わりに、外部管理ポインタでネイティブ呼び出しの結果を格納する

+0

Cの構造体をネイティブJavaオブジェクトにロードするのではなく、JNIを使​​用する魅力的な理由はありますか? –

+0

Cの構造体は、Cライブラリによって多くの計算の結果です。 CからJavaオブジェクトを埋める別の方法はありますか? – user48956

答えて

1

あなたは、単一のJNI呼び出しですべてのデータを移動したいです。プリミティブなバイト配列にコピーしてから(ByteArrayOutputStreamとDataOutputStreamの組み合わせを使ってJavaプリミティブを抽出する)、直接NIO ByteBuffer(ByteBuffer.allocateDirect)を使うことができます。 。直接のByteBufferは、特にVMとネイティブコードとの間のメモリを共有するために設計および最適化されています。

1

、あなたはそれがJavaオブジェクトに結果を返す可能性があります。

あなたはまた、返すことができます最も簡単には、などをまっすぐbyte[]にC構造体をmemcpyをした後、Java側に、ByteBufferにその配列をラップし、getInt()getFloat()でそれを読むことであろうあなたの構造体を反映するために構築されたJavaオブジェクトの配列が、コードは、明示的なメモリ管理との反射により、すべてを構築するにやや似信じられないほどの混乱、だろう。

関連する問題