我编写了JNI包装器来导出嵌入JVM的C应用程序(G-WAN)的API。本机调用在C应用程序中实现,并使用RegisterNatives()导出。
理想情况下,我会为G-WAN API设置一个'gwan'类:
import gwan // G-WAN API
public class hello {
public static int jmain(long env, String[] args) {
gwan.xbuf_cat(gwan.get_reply(env), "Hello World");
return 200; // HTTP status (200:'OK')
}
}
我想做一些像上面的“#import gwan”来导入本机调用 prototypes ,但是目前我只有以下(有效):
public class hello {
public static int jmain(long env, String[] args) {
gwan_xbuf_cat(gwan_get_reply(env), "Hello World");
return 200; // HTTP status (200:'OK')
}
public static native long gwan_get_reply(long env);
public static native void gwan_xbuf_cat(long ctx, String str);
}
同样,G-WAN可执行文件中的本机调用的实现(不是存储在磁盘上的Java类)。
因为the G-WAN API is quite large,我希望在可能的情况下将本机调用原型放在他们自己的'gwan'类(或命名空间)中(比如上面的第一个hello示例)。
有关如何做到这一点的任何建议? (请发布Java或JNI代码,因为我不是Java专家)
Disclamer:我参与了这个项目的开发。
答案 0 :(得分:2)
我建议您阅读以下关于JNI的文章,现在来自Sun的Oracle http://java.sun.com/docs/books/jni/html/jniTOC.html
之后它应该是可以理解的,但是一些伪代码和未经测试的将是将两个gwanapi调用移动到它自己的名为gwanapi.java的文件中
public class gwanapi {
public static native long get_reply(long answer);
public static native void xbuf_cat(long ctx,String str);
}
然后用javac gwanapi.java
编译该文件 - >输出:gwanapi.class
为c / c ++头实现键入javah -jni:
javah -jni gwanapi
你的hello java类中的下一个应该是调用static{ System.loadLibrary("gwanapi");}
伪代码而未经过测试
public class hello{
static{
System.loadLibrary("gwanapi");
}
public static int jmain(long env,String args[]){
gwanapi.xbuf_cat(gwanapi.get_reply(env),"Hello World!");
return 200;
}
}
你应该好好去。
但我可能错过了一两点,但我认为这是你应该做的最少量的工作。
哦顺便说一句,http://en.wikipedia.org/wiki/Java_Native_Interface也是JNI调用的某种形式的来源及其工作方式,并引导您访问更多有更多信息的网站。
由于
答案 1 :(得分:2)
作为一名C程序员,我不得不阅读JVM的C源代码,发现Java使用点而不是斜杠重新映射类(路径)名称。
由于G-WAN目录层次结构使用IP地址来定义侦听器和虚拟主机(192.168.10.10_80/#domain.com/csp
),因此这些点混淆了FindClass()
JNI调用,使其无法找到类。
我还发现类路径路径分隔符是":"对于Unix和&#34 ;;"对于Windows。这不是我的问题的原因,但它可能会导致同样的问题。
最后,我停止使用GCJ编译器的JVM,因为它不支持格式化doubles
(至少从2006年开始)。使用OpenJDK或SUN / ORACLE JVM按预期工作。
现在一切正常。我在这里发布所有这些以防万一它可以帮助其他人。