Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为JDK 10中的类文件生成JNI头文件_Java_Java Native Interface_Javah_Java 10 - Fatal编程技术网

Java 为JDK 10中的类文件生成JNI头文件

Java 为JDK 10中的类文件生成JNI头文件,java,java-native-interface,javah,java-10,Java,Java Native Interface,Javah,Java 10,Java本机接口(JNI)的一个组成部分是通过C头连接JVM代码和本机代码。生成这些头文件的方法过去非常简单:只需对类文件调用命令行实用程序javah。然后,该过程将为标记有native修饰符的任何方法生成原型 但是,从Java10开始,javah实用程序及其建议的替换是javac的一个新标志“-h”。如果有可用的Java源文件,那么替换就可以了,但是在只有编译类文件可用的情况下,替换就不够了。(引发这个问题的问题是,我试图从Scala源代码生成JNI绑定。我目前的方法是先编译它们,然后在生成的

Java本机接口(JNI)的一个组成部分是通过C头连接JVM代码和本机代码。生成这些头文件的方法过去非常简单:只需对类文件调用命令行实用程序
javah
。然后,该过程将为标记有
native
修饰符的任何方法生成原型

但是,从Java10开始,
javah
实用程序及其建议的替换是javac的一个新标志“-h”。如果有可用的Java源文件,那么替换就可以了,但是在只有编译类文件可用的情况下,替换就不够了。(引发这个问题的问题是,我试图从Scala源代码生成JNI绑定。我目前的方法是先编译它们,然后在生成的类文件上运行javah。)


在只有编译过的类文件可用的情况下,是否有一种生成C头文件的方法,类似于
javah
过去的方法?

您总是可以通过
javap
。我知道,我知道。它很难看,有很多假设,但如果您迫切需要为许多文件生成标题,它可能是唯一的选择

#!/bin/bash

# FIRST_ARG - full class name (with package)
# SECOND_ARG - class path

CLASS_NAME=`javap -cp $2 $1 | \
  grep -v "Compiled from" | \
  grep "public class" | \
  cut -f3 -d" " | \
  awk -F"." '{ print $NF }'`

PACKAGE_NAME=`javap -cp $2 $1 | \
  grep -v "Compiled from" | \
  grep "public class" | \
  cut -f3 -d" " | \
  sed s/\.${CLASS_NAME}$//`

DIR_NAME=`echo $PACKAGE_NAME | sed 's|\.|/|g'`
mkdir -p java_jni/${DIR_NAME}

JAVA_FILE_NAME="java_jni/${DIR_NAME}/${CLASS_NAME}.java"

echo "package ${PACKAGE_NAME};" > ${JAVA_FILE_NAME}
echo "public class ${CLASS_NAME} {" >> ${JAVA_FILE_NAME}

javap -cp $2 $1 | grep "native" | while read line; do
  param=0
  comma=`echo $line | grep "," | wc -l`
  while [ $comma -gt 0 ]; do
    line=`echo $line | sed "s/,/ param_${param}|/"`
    let param=param+1
    comma=`echo $line | grep "," | wc -l`
  done
  line=`echo $line | sed "s/)/ param_${param})/" | sed 's/|/,/g'`
  echo "  $line" >> ${JAVA_FILE_NAME}
done

echo "}" >> ${JAVA_FILE_NAME}

mkdir -p c_header
javac -h c_header ${JAVA_FILE_NAME}
我打赌它会变得更漂亮


对我来说,现在,当我慢慢开始考虑不可避免地向Java10发展时,所有这些情况下,我可能会对不存在的Java源代码感到惊讶,我认为拥有一些工具供我使用不是一个坏主意。以防万一。

我们可以用来生成JNI头文件。

我认为最好的解决方案就是安装jdk8。
无需卸载jdk10,只需修改环境变量。

可能只是假设,但是否将scala源代码编译成jar,然后在类路径上使用jar作为
javac-h
标志不是一个选项?有一个基于
javap
的丑陋解决方案。您可以反编译类,只保留本机内容,并使用javac将内容编译回来。但这是一种非常丑陋的方法,不幸的是,您提出的解决方案不起作用。javac在源代码中确实需要本机修饰符。目前,mko的答案看起来是最有希望的。关于Kotlin使用javah的类似问题:如果本机方法采用参数(javac抱怨错误:预期),这似乎不起作用。感谢您在Salomonbris发现它!!