我在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;
}
现在我有两个功能:打开和 sendData 在 打开 函数中我正在初始化skt和ifr中的一些值。并希望在我的 senddata 功能中访问这些数据。但是当我打印我的日志时,打开功能正常工作但sendData函数无法访问在open函数中初始化的skt值。默认它的“0”。请指导我如何实现这一目标。
答案 0 :(得分: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);
}
}