在JDK 10中为类文件生成JNI头文件

Jak*_*sky 9 java java-native-interface javah java-10

Java Native Interface(JNI)的一个组成部分是通过C头桥接JVM代码和本机代码.生成这些头文件的方法过去非常简单:只需javah在类文件上调用命令行实用程序即可.然后,此过程将为使用native修饰符标记的任何方法生成原型.

但是,从Java 10开始,该javah实用程序已被删除,其建议的替换是javac的新标志"-h".如果有可用的Java源文件,则替换可以正常工作,但是只有编译的类文件可用时才会出现问题.(引发这个问题的问题是我正在尝试从Scala源生成JNI绑定.我当前的方法是首先编译它们然后在生成的类文件上运行javah.)

在只有编译的类文件可用的情况下,有没有办法生成C头文件,类似于以往的方式javah

Oo.*_*.oO 5

你可以随时通过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}
Run Code Online (Sandbox Code Playgroud)

我打赌它可以变得更漂亮.

对我来说,现在,当我慢慢开始考虑不可避免地转向Java 10时,以及所有这些情况,我可能会对现有的Java源代码感到惊讶,我认为拥有一些工具并不是一个坏主意.以防万一.


小智 5

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