【问题标题】:Java and JNI global variablesJava 和 JNI 全局变量
【发布时间】:2025-08-01 04:15:01
【问题描述】:

我需要帮助,因为我不知道该怎么做。我是 JNI 的新手。

我正在开发一个 Android 应用程序,它必须使用特定协议 (OpenIGTLink)。

为了使用这个协议,我使用了一个 C 库。问题是我需要定义一个全局变量来存储连接。您可以在下一个示例中看到:

igtl::ClientSocket::Pointer socket;


Java_es_iac_iactec_infraredsend_Comunicacion_OpenIGTLink_connect(
    JNIEnv *env,
    jobject mjobject,
    jstring host,
    jint port) {
socket = igtl::ClientSocket::New();

const char *chost = env->GetStringUTFChars(host, 0);

int r = socket->ConnectToServer(chost, port);
if (r != 0) {

    return (jstring) "Cannot connect to the server.";
}

return (jstring) "ok";
}

以及我想做的其他方法:

 Java_es_iac_iactec_infraredsend_Comunicacion_OpenIGTLink_send() {
    igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New();
    imgMsg->SetDimensions(size);
    imgMsg->SetSpacing(spacing);
    imgMsg->SetScalarType(scalarType);
    imgMsg->SetDeviceName("ImagerClient");
    imgMsg->SetSubVolume(svsize, svoffset);
    imgMsg->AllocateScalars();
    imgMsg->Pack();

    socket->Send(imgMsg->GetPackPointer(), imgMsg->GetPackSize());
 }

我不知道我是否必须声明一个 java 全局变量来存储 de socket 对象并从 JNI 访问它,或者是否可以像在 cpp 文件中定义一个全局变量一样定义套接字。

谢谢大家,对不起我的英语。

【问题讨论】:

  • 没有Java目标变量之类的东西,很难知道你在说什么。
  • 感谢您的回复。我试着解释我的项目。我想从 movil 相机发送 OpenIGTLink 图像。我有 C++ 中的代码,可以将一些图像从 de sdcard 发送到服务器。现在我想从相机发送图像,所以我有一个 SurfaceView 来预览相机图像。我在想的过程是,从 Java 调用一个 JNI 函数来建立与服务器的连接,然后从 java 调用另一个 JNI 函数来发送图像。非常感谢你!

标签: java android c++ java-native-interface


【解决方案1】:

也许,这不是最好的方法,但我们正在这样做。 我们将一个从 JNI 到 Java 的指针作为 jlong​​ 返回,并将它传递给每个调用。它的工作方式类似于指向方法中对象的自指针。在你的情况下,它看起来像这样

jlong Java_es_iac_iactec_infraredsend_Comunicacion_OpenIGTLink_connect(
     JNIEnv *env,
     jobject mjobject,
     jstring host,
     jint port) {
     /*some code*/
     return reinterpret_cast<jlong>(socket);
 }

然后

 Java_es_iac_iactec_infraredsend_Comunicacion_OpenIGTLink_send(jlong pointer) {
    /*some code*/
    igtl::ClientSocket::Pointer socket = reinterpret_cast<igtl::ClientSocket::Pointer>(pointer)
    socket -> Send(imgMsg->GetPackPointer(), imgMsg->GetPackSize());
 }

【讨论】:

  • 非常感谢您的回答。当我尝试执行您的解决方案时,我收到下一个编译器错误:错误:错误:没有匹配的 C 样式转换从 'igtl::ClientSocket::Pointer' (aka 'SmartPointer<:clientsocket>') 到 ' jlong​​'(又名'长')。所以我不能使用你的解决方案。请问您还有什么想法吗?非常感谢!!
  • 我不是 C++ 专家,但您认为应该使用 reinterpret_cast。我会尝试更改示例。