Java 如何生成特定的JNI头

Java 如何生成特定的JNI头,java,c,header,java-native-interface,javah,Java,C,Header,Java Native Interface,Javah,我有一个.dll库,它以以下格式导出函数: _Java_folder1_folder2_folder3_JavaClassName_javamethodname@16 我无法修改.dll。它是给我的 我需要编写一个java程序来调用本机javamethodname。但是,我无法生成正确的头文件。如何生成具有上述签名的头文件 我尝试了javah-jnijavaclassname,但它没有给我想要的结果。当我从目录层次结构内部调用javah时,会得到一个如下的头: Java_JavaClassNam

我有一个.dll库,它以以下格式导出函数:

_Java_folder1_folder2_folder3_JavaClassName_javamethodname@16

我无法修改.dll。它是给我的

我需要编写一个java程序来调用本机
javamethodname
。但是,我无法生成正确的头文件。如何生成具有上述签名的头文件

我尝试了javah-jnijavaclassname,但它没有给我想要的结果。当我从目录层次结构内部调用javah时,会得到一个如下的头:

Java_JavaClassName_javamethodname

当我试图从目录层次结构之外调用javah时,我得到了一个错误

另外,如何在Java前面获取标题签名中的下划线?也就是说:_Java不是Java


谢谢

将Java类放在folder1.folder2.folder3包中

C源代码将命名为“Java_folder1_folder2_folder3_JavaClassName_javamethodname”,不带下划线


您将需要确定本机方法所需的参数。

如果DLL尚未附带具有本机方法声明的相应Java类,则它是不完整的,可能100%无用。不应该期望您对其进行反向工程。它甚至可能是错误建造的。在我进一步讨论这个问题之前,我会要求证据证明它是有效的。证据必须包括Java部分;否则它就不是证据。

编写java代码很容易:您使用包名创建一个java项目folder1.folder2.folder3,并使用
原生javamethodname
将类
JavaClassName
放在其中。您不需要生成头或任何东西,这是由创建DLL的人完成的,并且与您正在重建的类相同

并且是由JVM-JNI链接器添加的,您不需要关心它

然而,我在字里行间读到,您的前导下划线也有问题。这是一个“编译器装饰”,如果你只得到了DLL(没有源代码,没有重新编译),那么你也可能会失败。各种编译器添加了各种“装饰”,以确保不会混淆调用方(JVM)和被调用方(DLL)之间的调用约定。它有一些,可能会被和/或定义文件(.def on MSVC)损坏。这两种情况都不适用于您的情况。因此,您需要:

  • 找出用于生成DLL的编译器
  • 查找给定编译器为其生成观察到的符号装饰的调用约定
  • DLL只能通过JVM运行,JVM在
    $JAVA\u HOME/include/Your\u platform/jni\u md.h

  • 如何在包上调用javah?如何获得Java前面的前导下划线,比如Java?谢谢@skyknight——运行
    javah
    对你没有好处
    javah
    对Java本机类进行操作,以生成一个.h文件来编译本机方法。您已经有了已编译的本机方法。在javah命令中,您还需要用包完全限定类名。我认为在构建DLL时,您将看到下划线。也就是说,您已经有了一个DLL。如果已经有DLL,为什么需要头文件?@AndyThomas-Cramer,重新生成头文件有助于调试。否则,当代码无法运行时,我得到的信息很少。当从eclipse插件调用.dll时,它运行良好。因此,这是好的。问题是我必须为它编写一个命令行界面。Eclipse做了一些奇怪的事情。@skyknight如果你已经有了DLL和Java类,我不明白你为什么需要重新生成任何东西。实际上,重新生成有助于更轻松地调试。如果标头与.dll中的预期函数调用不匹配,它将不会运行。为什么?您已经有了Java类和DLL。这就是你所需要的。只需编写调用Java类的Java代码。是的,为什么需要标头?您需要的是Java本机类,您应该能够从任何调用DLL的JAR文件中提取该类。然而,这里似乎有一些软件保护,它们检查是否初始化了某些变量以及是否加载了某些类。似乎还有更多,因为我无法获得预期的输出:(