JNA:EXCEPTION_ACCESS_VIOLATION

时间:2015-04-09 12:10:17

标签: java c++ fatal-error jna

我通过JNA使用C ++ DLL。 我想在Java中调用以下方法,该方法写入我想要读取的szVisor信息。

long FAR PASCAL DLL_GetLocalPortTS(char* szEquip,char* szVisor){
    ...
}

Java接口实现如下:

public interface IE2E extends Library {
    // Instancia de la dll, carga la librería
    IE2E INSTANCE = (IE2E) Native.loadLibrary("e2e", IE2E.class);
    ...
    int GetLocalPortTS(String equip, String[] equipInfo);
}

方法调用:

String equip = "equipID";
String equipInfo = "";
String[] rEquipInfo = {equipInfo};
IE2E sdll = IE2E.INSTANCE; 

int ret = sdll.GetLocalPortTS(equip, rEquipInfo);

这个执行在JRE中给我一个致命的错误,但如果我把两个参数都作为String或String [],它就不会。但是,如果我同时使用两个字符串,它不会覆盖equipInfo并且我不会得到我想要的信息;如果我同时使用它们作为数组,该方法不会获得装备值并且不会运行。

欢迎任何有关此事的见解。

1 个答案:

答案 0 :(得分:2)

问题是C代码想要写入szVisor,对吗?我想它确实是这样的:

long GetLocalPortTS(char* szEquip,char* szVisor){
    strcpy(szVisor, "I am C code result :)");
    return 0;
}

如果从Java端传入String,那么内存由JVM拥有,因此写入它会导致崩溃。你需要的是一个Memory对象,它是一个包装的malloc内存,C代码可以安全地写入。

您的新JNA界面如下所示。我已经注释掉了旧版本,因此您可以进行比较:

public interface IE2E extends Library {
    IE2E INSTANCE = (IE2E) Native.loadLibrary("e2e", IE2E.class);
    //int GetLocalPortTS(String equip, String[] equipInfo);
    int GetLocalPortTS(String equip, Memory equipInfo);
}

调用它的代码如下,256是占位符。确保分配足够的内容以将字符串写入:

String equip = "equipID";
String equipInfo = "";
//String[] rEquipInfo = {equipInfo};
Memory rEquipInfo = new Memory(256);
IE2E sdll = IE2E.INSTANCE;
int ret = sdll.GetLocalPortTS(equip, rEquipInfo);

要将结果用作String,您可以这样做:

rEquipInfo.getString(0);

正如文档所述,Memory的finalize()方法会自动在malloc内存上调用free,因此无需担心内存泄漏。