6

.cpp ファイルが jbyteArray を取得する JNI プログラムを作成しており、jbyteArray を printf で出力できるようにしたいと考えています。そのためには、jbyteArray を文字配列に変換する必要があると思います。

背景知識として、JNI の Java 側で String を byteArray に変換し、その byteArray を引数として JNI 関数に渡します。

これまでに行ったことは文字列を正しく出力しますが、その後にジャンク文字が続き、これらを取り除く方法がわかりません/何か間違ったことをしている場合。

文字列とは次のとおりです。

dsa

そしてコンソールに出力されるもの:

dsa,�

String が何であるかによってジャンク文字が変わります。関連するコードの部分は次のとおりです。

.java ファイル:

public class tcr extends javax.swing.JFrame{

static{
    System.loadLibrary("tcr");
}

public native int print(byte file1[]);

    .....

    String filex1 = data1TextField.getText();//gets a filepath in the form of a String from a GUI jtextfield.
    byte file1[]= filex1.getBytes();//convert file path from string to byte array

        tcr t = new tcr();
        t.print(file1);
}

.cpp コード:

JNIEXPORT jint JNICALL Java_tcr_print(JNIIEnv *env, jobject thisobj, jbyteArray file1){

    jboolean isCopy;
    jbyte* a = env->GetByteArrayElements(file1,&isCopy);
    char* b;
    b = (char*)a;
    printf("%s\n",b);
}

どんな助けでも大歓迎です。

4

2 に答える 2

2

jbyteArray は、実際には JNI を介して Java String を渡すための非常に優れた方法です。文字列を、C++ 側で使用しているライブラリとファイル/デバイスに必要な文字セットとエンコーディングに簡単に変換できます。

「すべてのソフトウェア開発者が絶対に、積極的に Unicode と文字セットについて知っておく必要がある絶対最小値 (言い訳はありません!)」を必ず理解してください。

Java String は、Unicode 文字セットと UTF-16 エンコーディング (プラットフォームに依存するバイト順) を使用します。

String.getBytes()は、「プラットフォームのデフォルトの文字セット」に変換します。したがって、必要な文字セットとエンコーディング、およびターゲット文字セットにない文字をどうするかについて仮定しています。これらを明示的に制御したい場合は、他の Java String.getBytes オーバーロードまたは Charset メソッドを使用できます。

使用する文字セットとエンコーディングを決定する際には、Unicode が Java、.NET、VB などで主要な文字列型として数十年にわたって使用されてきたことを考慮してください。Java のコンパイラ ソース ファイルでは、...; 一般的には WWW で。もちろん、相互運用したいものによって制限される場合があります。

現在、あなたが直面している問題は、ターゲット文字セットに Java String の文字が欠落しており、代替が使用されているか、使用しているコンソールがそれらを正しく表示していないことです。

コンソール (または UI を備えた任意のアプリ) は、明らかに、文字をレンダリングする書体を選択する必要があります。通常、書体は Unicode で利用可能な 100 万のコードポイントをサポートしていません。コンソールの構成を変更する (または別のものを使用する) ことができる場合があります。たとえば、Windows では、cmd.exe または ps (Windows PowerShell) を使用できます。Cmd.exe ウィンドウでフォントを変更し、 を使用chcpして文字セットを変更できます。

アップデート:

@main-- が指摘するように、文字列にターミネータが追加されることを期待する関数を使用する場合は、JVM が配列の所有権を保持するため、通常は配列をコピーして提供する必要があります。これが、この場合の動作の実際の原因です。ただし、上記のすべても関連しています。

于 2013-07-05T16:08:55.163 に答える