2

私は現在、CAndroidを使用するアプリケーションを開発しています。native C library.私は C に非常に慣れておらず、変換の問題がいくつかあります。問題が符号付き/符号なしの数値に関係していることはわかっていますが、これを修正するために何をする必要があるかわかりません。

C ライブラリは単独で正常に動作し、正しい結果を生成します。ただし、Android に移植すると、正の値のみが正しくなります。負の値は、256 から値を引いたものとして返されます。

例えば:

 8 -> 8
 5 -> 5
 1 -> 1
 0 -> 0
-3 -> 253
-5 -> 251
-8 -> 248

値を割り当てるときの C コードは次のようになります。

BYTE *parms;
WORD __stdcall GetValue(BYTE what, long *val){

    char myStringParmsOne[255];
    sprintf( myStringParmsOne, "parms[1]=%d", parms[1] );
    LOG_INFO( myStringParmsOne );

    char myStringIsG[255];
    sprintf( myStringIsG, "API_isG=%d",API_isG );
    LOG_INFO( myStringIsG );

    char myStringCharParmsB[255];
    sprintf( myStringCharParmsB, "(char)parms[1]=%d", (char)parms[1] );
    LOG_INFO( myStringCharParmsB );

    *val=(char)parms[1]-(API_isG?11:0);
}

LOG_INFOステートメントは、値を に出力しますLogCat。以下に、プログラムが実行されたときの値があり、値-3が期待されます。

The first **parms[1]=%d** statement returns **parms[1]=253**

The second **API_isG=%d** statement returns **API_isG=0**

The third **(char)parms[1]=%d** statement returns **(char)parms[1]=253**

BYTE および WORD タイプは次のように定義されます。

typedef unsigned char BYTE;
typedef unsigned short WORD;

この値を Java に送り返すために使用するラッパー関数を以下に示します。

long Java_my_package_Model_00024NativeCalls_GetValueJava( JNIEnv *env, jobject obj, WORD what) {
    long c;
    int j = GetValue( what, &c );
    if( j == 0 ) {
        return c;
    } else {
        return -1;
    }
}

編集

メソッドは常に使用されますGetValueが、この個々の呼び出しのみが負の数の問題を引き起こし、他の呼び出しで機能します。ラッパー関数に対して次の 2 つのことを試しました。

long Java_my_package_Model_00024NativeCalls_GetValueJava( JNIEnv *env, jobject obj, WORD what) {
    long c;
    int j = GetValue( what, &c );
    if( j == 0 ) {
        return (signed char)c;
    } else {
        return -1;
    }
}

上記の戻り値のキャストにより、適切な戻り値が得られます。ただし、他の値に対するこの関数への他のすべての呼び出しは、完全に面倒です。

long Java_my_package_Model_00024NativeCalls_GetValueJava( JNIEnv *env, jobject obj, WORD what) {
    long c;
    int j = GetValue( what, &c );
    if( j == 0 ) {
        return (signed long)c;
    } else {
        return -1;
    }
}

上記の戻り値のキャストは何も変更しませんでした。

4

2 に答える 2

2

これは、long 内に unsigned char (NDK char の IIRC はデフォルトで unsigned) を入れているために発生します。long の中に入れた値が符号付きの場合、コンパイラは long の符号ビットも変更します。

からキャストを変更してみてください

*val=(char)parms[1]-(API_isG?11:0);

*val=(long)((signed char)parms[1]-(API_isG?11:0));

((長い)キャストが必要かどうかはわかりませんが、おそらく(signed char)へのキャストで十分です。

于 2013-07-25T16:56:00.900 に答える