1

[1]によれば、返されるintはネイティブfdであると述べている ParcelFileDescriptor.getFd() から取得したJAVA fdを渡すAndroid用のアプリケーションを作成しています。

さて、この fd を使用して、UNIX ドメイン ソケットを介してリッスンしている既存のプロセスに書き込もうとしています。これを行うために、私は JNI を使用しており、上記で受け取った int をfdToSendという名前の引数として JNI 関数に渡します。

私の JNI コードが sendmsg() を呼び出そうとすると、「Bad file number」というエラーが発生します。

Google の助けを借りて、sendmsg() を呼び出すとソケット接続が閉じられるように見えますが、これがどのようになるかわかりません。

sendfd() メソッドは、[2] にあるものとまったく同じです。

以下は、ブリッジ JNI 関数です。

JNIEXPORT jint JNICALL Java_com_example_myapp_AppManager_bridgeSendFd(JNIEnv *env, jint fdToSend) {
    int fd;
    struct sockaddr_un addr;

    if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        __android_log_print(ANDROID_LOG_ERROR, APPNAME, "socket() failed: %s (socket fd = %d)\n", strerror(errno), fd);
        return (jint)-1;
    }

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, "/data/data/com.example.myapp/sock_path", sizeof(addr.sun_path)-1);

    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        __android_log_print(ANDROID_LOG_ERROR, APPNAME, "connect() failed: %s (fd = %d)\n", strerror(errno), fd);
        return (jint)-1;
    }

    return (jint)sendfd(fd, (int)fdToSend);
}

[1] http://developer.android.com/reference/android/os/ParcelFileDescriptor.html#getFd()

[2] https://stackoverflow.com/a/4491203/2796346

4

1 に答える 1

1

問題は JNI 関数の宣言であることが判明しました。

最初の引数は JNIEnv で、2 番目は jclass で、Java から渡された値です (つまり、私にとっては fdToSend)。

したがって、私の推測では、2 番目の引数 (jclass であると思われる) を使用していたため、おそらくメモリ参照またはそのような奇妙なものを取得しています。

ここに見られるように: https://stackoverflow.com/a/10743451/2796346

于 2013-10-07T14:04:36.943 に答える