我在JAVA中有一个原生函数
package mypackage;
public class MyWrapper {
private native int
wrapFilterRawRequest(String config, String rawRequest);
public void
processRequest( String configPath,String rawRequest){
int status = 0;
status = new MyWrapper().wrapFilterRawRequest(configPath, rawRequest);
status2 = new MyWrapper().wrapFilterRawRequest(configPath, rawRequest);
}
static{
System.loadLibrary("mylibrary");
}
}
和C中的JNI包装器相同
int processRequest(char *conf, char *req)
{
int status = 0;
// Do something here
return status;
}
JNIEXPORT jint JNICALL Java_mypackage_MyWrapper_wrapFilterRawRequest
(JNIEnv *env, jobject obj, jstring config, jstring rawRequest)
{
jint status = 0;
const char *conf, *req;
char *conf_copy, *req_copy;
conf = (env)->GetStringUTFChars(config, NULL);
req = (env)->GetStringUTFChars(rawRequest, NULL);
copy_str(&conf_copy, conf);
copy_str(&req_copy, req);
(env)->ReleaseStringUTFChars(config, conf);
(env)->ReleaseStringUTFChars(rawRequest, req);
status = processRequest(conf_copy , req_copy );
return status;
}
当我在JAVA中两次调用本机函数时,它给了我一个错误,因为它等同于连续两次调用C函数processRequest(char *,char *),这是我的应用程序不支持的。我希望每次都可以独立调用它,类似于运行两次可执行文件时的方式。 (程序在调用两次时有效,但在同一应用程序中调用两次相同的函数时则无效)。我希望JNI在进行本机调用时重新初始化所有内容。我怎样才能做到这一点?
答案 0 :(得分:5)
嗯,您可以尝试从JVM中卸载dll,方法是使用自己的ClassLoader
加载必要的类,执行您需要的操作,将值设置为null
,然后调用System.gc()
来获取摆脱实例及其dll的旧痕迹,然后通过重新启动实例将dll重新加载到JVM中:
package test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
*
* @author David
*/
public class Test {
static {
System.loadLibrary("mydll.dll");
}
@Override
public void finalize() {
System.out.println("A garbage collected");
}
public void print(String str, int value) {
System.out.println(str);
System.out.println(value);
}
public static int getNumber() {
return 42;
}
public static void main(String[] args) throws Exception {
Class<?> clazz = Test.class;//class name goes here
// static call
Method getNumber = clazz.getMethod("getNumber");
int i = (Integer) getNumber.invoke(null /*
* static
*/);
// instance call
Constructor<?> ctor = clazz.getConstructor();
Object instance = ctor.newInstance();
Method print = clazz.getMethod("print", String.class, Integer.TYPE);
print.invoke(instance, "Hello, World!", i);
print = null;
instance = null;
ctor = null;
getNumber = null;
clazz = null;
i = 0;
System.gc(); //reload by empting garbage Class<?> clazz = Test.class;//class name goes here
clazz = Test.class;//class name goes here
// static call
getNumber = clazz.getMethod("getNumber");
i = (Integer) getNumber.invoke(null /*
* static
*/);
// instance call
ctor = clazz.getConstructor();
instance = ctor.newInstance();
print = clazz.getMethod("print", String.class, Integer.TYPE);
print.invoke(instance, "Hello, World!", i);
print = null;
instance = null;
ctor = null;
getNumber = null;
clazz = null;
i = 0;
System.gc(); //reload by empting garbage
}
}
<强>参考:强>