所以我想知道是否有可能以及如何将套接字从 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/