1

我在 android 中创建了一个运行良好的本机应用程序。此应用程序基于套接字编程。所以首先我必须打开我想要处理我的数据的那个端口,然后在需要关闭之后处理代码。但问题是,由于我是 ndk 编程的新手,我能够以相同的功能打开和处理数据,但我想要一种模块化的方法。首先我想创建一个打开函数,然后发送数据并关闭。为此,我需要创建一些全局变量,以便可以在其他函数中使用它们。像下面这样:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LOG_TAG "native"
int skt;          // i want to use skt and ifr values
struct ifreq ifr;

JNIEXPORT jint JNICALL Java_com_can_demo_NativeControls_Open(JNIEnv * env, jobject obj, jstring port)
{
    if ((skt = socket(PF_, SOCK_RAW, _RAW)) < 0) {
        LOGI( "socket not opend");
    }

    strcpy(ifr.ifr_name, port);
    if( ioctl(skt, SIOCGIFINDEX, &ifr) < 0)
    {
        LOGI( "interface not opend");
    }

    addr._family = AF_;
    addr._ifindex = ifr.ifr_ifindex;

    if(bind (skt, (struct sockaddr*)&addr, sizeof(addr)) <0 )
    {
        LOGI( "bind Error");
    }
}

JNIEXPORT jint JNICALL Java_com_can_demo_NativeControls_Send(JNIEnv * env, jobject obj, jstring path)
{
    const jbyte *str;

    frame._id = 0x123;
    str = (*env)->GetStringUTFChars(env, path, 0);
    strcpy( frame.data, str );
    frame.can_dlc = strlen( frame.data );
    int bytes_sent = write( skt, &frame, sizeof(frame) );
    return bytes_sent;
}

现在我有两个函数:open函数 中的opensendData我正在初始化 skt 和 ifr 中的一些值。并想在我的senddata函数中访问这些数据。但是当我打印我的日志时,打开函数正常工作但 sendData 函数无法访问在打开函数中初始化的 skt 值。默认为“0”。请指导我如何实现这一目标。

4

1 回答 1

1

首先,0对于套接字来说,这是一个完全正确的值。因此,您的全局变量按预期访问。

但是您的代码需要改进。我在评论中解释了一些技术问题。但我强烈建议不要像在此代码段中那样使用全局变量。处理本机句柄(例如指针)的推荐方法是将值返回给 Java(可能是jlong),并在您的 JNI 函数必须使用此值时将其从 Java 传递回本机。有一些技术允许本机代码访问 Java 对象的字段以设置/检索此类信息,但在像您这样的简单情况下,它是一个过冲。这是Java中的一个简单示例:

public class NativeControls {

    private long _nativeSocket = -1;

    private native long Open(String port);

    public void open(String port) {
        _nativesocket = Open(port);
    }

    private native int Send(long socket, String path);
    public void sendData(String path) {
        return Send(_nativesocket, port);
    }
}
于 2012-10-23T21:30:17.213 回答