Как передать java.net.Socket в функцию DLL C ++, ожидающую `BoostSocket.assign (tcp :: v4 (), nativeSocketFromJava);` - PullRequest
6 голосов
/ 01 августа 2011

Так что мне интересно, возможно ли это, и как передать сокет из Java в библиотеку DLL, ожидающую родной для этого сокета ОС?Может ли кто-нибудь привести пример?Можно ли как-нибудь использовать для этого org.apache.tomcat.jni.Socket?

1 Ответ

3 голосов
/ 04 августа 2011

Первым делом - нам нужно получить файловый дескриптор java.net.Socket. Это можно сделать с помощью механизма отражения. Идея состоит в том, чтобы получить доступ к java.io.FileDescriptor на java.net.SocketImpl, а затем получить собственный дескриптор сокета. См. DualStackPlainSocketImpl.java для фрагментов кода (этот метод также указан Зораном Регвартом здесь ).

Другой метод заключается в использовании JNI, как обсуждено здесь , вот пример:

static int getFd(JNIEnv *env, jobject sock)
{
    JNIEnv e = *env;
    jclass clazz;
    jfieldID fid;
    jobject impl;
    jobject fdesc;

    /* get the SocketImpl from the Socket */
    if (!(clazz = e->GetObjectClass(env,sock)) ||
        !(fid = e->GetFieldID(env,clazz,"impl","Ljava/net/SocketImpl;")) ||
        !(impl = e->GetObjectField(env,sock,fid))) return -1;

    /* get the FileDescriptor from the SocketImpl */
    if (!(clazz = e->GetObjectClass(env,impl)) ||
        !(fid = e->GetFieldID(env,clazz,"fd","Ljava/io/FileDescriptor;")) ||
        !(fdesc = e->GetObjectField(env,impl,fid))) return -1;

    /* get the fd from the FileDescriptor */
    if (!(clazz = e->GetObjectClass(env,fdesc)) ||
        !(fid = e->GetFieldID(env,clazz,"fd","I"))) return -1;

    /* return the descriptor */
    return e->GetIntField(env,fdesc,fid);
}

Полагаю, вы говорите о TCP-сокете Boost.Asio. Если это так, то вы должны связать собственный сокет с объектом сокета Asio, используя метод assign.

Имейте в виду, что это решение может не работать для определенных реализаций Java, так как оно использует внутренние детали реализации, которые, как гарантируют, не останутся прежними. Кроме того, убедитесь, что нет параллелизма (т.е. Java не пытается читать из одного и того же дескриптора сокета параллельно) и т. Д. Другими словами - используйте на свой страх и риск.

Надеюсь, это поможет. Удачи!

...