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

标签 java c++ sockets dll shared-libraries

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

最佳答案

首先,我们需要获取 java.net.Socket 的文件描述符。使用反射机制可以做到这一点。这个想法是访问 java.net.SocketImpl 上的 java.io.FileDescriptor,然后获取 native 套接字描述符。参见 DualStackPlainSocketImpl.java对于代码片段(Zoran Regvart here 也指出了这种方法)。

另一种方法是使用 JNI,如前所述 here ,这里是一个例子:

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);
}

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

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

希望对您有所帮助。祝你好运!

关于java - 如何将 java.net.Socket 传递给等待 `BoostSocket.assign(tcp::v4(), nativeSocketFromJava);` 的 C++ DLL 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6899868/

相关文章:

java - 尝试将墨西哥波浪风格图案中的字符更改为大写

c++ - 将私有(private)方法类成员作为指向函数的指针传递

javascript - Node.js:一次接收太多 UDP 消息,丢失它们

java - 使用java搜索JSon字符串

java - 在列表中获取 java.lang.UnsupportedOperationException

c++ - 头文件中的多重定义

Java 与。 C++/C 树实现,幕后发生了什么

sockets - 消息队列与套接字

Python - 我怎样才能让客户端能够多次连接?

java - 运行 Tomcat 服务器时出错