如何将java.net.Socket传递给等待`BoostSocket.assign(tcp :: v4(),nativeSocketFromJava)的C++ DLL函数;`

Rel*_*lla 6 c++ java sockets dll shared-libraries

所以我想知道是否有可能以及如何将套接字从java传递到某个DLL库等待本操作系统套接字的本机?可以有人提供一个例子吗?无论如何可以使用org.apache.tomcat.jni.Socket吗?

小智 3

首先,我们需要获取java.net.Socket. 使用反射机制可以做到这一点。这个想法是访问java.io.FileDescriptor然后java.net.SocketImpl获取本机套接字描述符。请参阅DualStackPlainSocketImpl.java参考资料 代码片段(Zoran Regvart 也指出了此方法

另一种方法是使用 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);
}
Run Code Online (Sandbox Code Playgroud)

我还假设您正在谈论 Boost.Asio 的 TCP 套接字。如果是这样,那么您必须使用方法将本机套接字与 Asio 的套接字对象关联起来assign

请注意,此解决方案可能不适用于某些 Java 实现,因为它使用的实现的内部细节不能保证保持不变。另外,请确保没有并发(即 Java 不会尝试并行地从同一个套接字描述符读取)等。换句话说 - 使用时需要您自担风险。

希望能帮助到你。祝你好运!