首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JNI包装器的多个实例

JNI包装器的多个实例
EN

Stack Overflow用户
提问于 2016-07-28 18:02:04
回答 1查看 580关注 0票数 1

我有一个Modbus类

代码语言:javascript
运行
复制
public class Modbus {
  // init TCP
  public native void init(String ip, int port, int id);
  public native short[] read_registers(int slaveid, int addr, int len);

如果我执行read_registers,初始化方法中的id将被打印到标准输出

如果我这样做了

代码语言:javascript
运行
复制
Modbus mb1 = new Modbus("192.168.0.250", 502, 1);
Modbus mb2 = new Modbus("192.168.0.250", 502, 2);

然后

代码语言:javascript
运行
复制
mb1.read_registers(....);
mb2.read_registers(....);

在这两种情况下,它都会将2输出到标准输出。因此,第二个实例似乎覆盖了第一个实例。如何使用jni-wrapper的多个实例?

编辑:

在这里我使用的C代码,我的目标是使用多个连接到samre或不同的modbus设备

代码语言:javascript
运行
复制
#include "eu_company_lib_comm_modbus_Modbus.h"
#include <modbus/modbus-rtu.h>
#include <modbus/modbus.h>
#include <errno.h>
modbus_t *mb;
int readError;
int writeError;
int errnr;
const char* errStr;
int c_id;
JNIEXPORT void JNICALL 
Java_eu_company_lib_comm_modbus_Modbus_init__Ljava_lang_String_2I(
    JNIEnv * env, jobject obj, jstring ip, jint port, jint id) {

const char* c_ip = (*env)->GetStringUTFChars(env, ip, 0);
mb = modbus_new_tcp(c_ip, port);
c_id=id;
if (mb == NULL) {
    fprintf(stderr, "Unable to allocate libmodbus context\n");
    fflush(stderr);
    return;
}
modbus_set_debug(mb, 1);

if (modbus_connect(mb) == -1) {
    fprintf(stderr, "Connection failed: %s\n",     modbus_strerror(errno));
    fflush(stderr);
    modbus_free(mb);
    return;
}

(*env)->ReleaseStringUTFChars(env, ip, c_ip);
}
JNIEXPORT jshortArray JNICALL Java_eu_company_lib_comm_modbus_Modbus_read_1registers(
    JNIEnv * env, jobject obj, jint slave_id, jint address, jint len) {

jshortArray result = (*env)->NewShortArray(env, len);
uint16_t tab_reg[len];
printf("%d\n",c_id);
fflush(stdout);
readError = modbus_read_registers(mb, address, len, tab_reg);

errnr = errno;
errStr = modbus_strerror(errno);

(*env)->SetShortArrayRegion(env, result, 0, len, tab_reg);

return result;
}
EN

回答 1

Stack Overflow用户

发布于 2016-07-29 18:27:02

您的主要问题是在JNI部分中使用的是全局变量。全局变量。因此,这些变量与Modbus实例没有任何关系。

在我看来,您应该将尽可能多的代码从JNI转移到ModBus的Java实现中,并使用本地字段来存储Java an JNI级别上需要的所有持久化值:

公共类Modbus {

代码语言:javascript
运行
复制
private final String ip;
private final int port;
private final int id;

public ModBus(String ip, int port, ind id) {
     this.ip = ip;
     this.port = port;
     this.id = id;
}    

// init TCP
public native void init(String ip, int port, int id);
public native short[] read_registers(int slaveid, int addr, int len);

}

在JNI端,您可以使用JNI方法GetObjectClass(..)GetFieldID(..)GetObjectField(..)访问所有用于检索值的Java字段。

搜索一下例子,你会找到很多C和C++的例子。

或者,您可以将本机方法设为私有方法,并添加一个包装器方法,该方法在每次调用时将所需的值传递给JNI部分:

代码语言:javascript
运行
复制
public void init() {
    init(ip, port, id);
}

private native void init(String ip, int port, int id);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38633147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档