簡體   English   中英

為JDK 10中的類文件生成JNI頭文件

[英]Generate JNI header files for class files in JDK 10

Java本機接口(JNI)的組成部分是通過C頭將JVM代碼和本機代碼橋接在一起。 過去,生成這些頭文件的方法非常簡單:只需在類文件上調用命令行實用程序javah 然后,此過程將為帶有本native修飾符的任何方法生成原型。

但是,從Java 10開始, 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}

我敢打賭,它可以變得更漂亮。

對我來說,現在,當我慢慢開始思考不可避免地向Java 10過渡的時候,在所有這些情況下,我可能會為不存在的Java源代碼感到驚訝,我認為擁有一些可用的工具並不是一個壞主意。 以防萬一。

我們可以使用gjavah生成JNI頭文件。

我認為,最好的解決方案是安裝jdk8。 無需卸載jdk10,只需修改環境變量即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM