JNI本机调用* prototypes *在他们自己的类/命名空间中?

时间:2012-02-18 06:50:15

标签: java c java-native-interface

我编写了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:我参与了这个项目的开发。

2 个答案:

答案 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按预期工作。

现在一切正常。我在这里发布所有这些以防万一它可以帮助其他人。