Rust JNIの原理
4658 ワード
1、Rust FFI
Rust言語自体はC言語インターフェースを提供し、ffiの形で直接Cライブラリの関数を呼び出すことができます。文法はこうです。
2、Java Native Interface
JNIフルネームJava Native Interfaceは、JavaとC/C++の間の通信の仕組みを実現し、JavaからC/C++にアクセスでき、C/C++からJavaにアクセスすることもできます。 Javaは、C/C++にアクセスし、Javaでは、nativeキー宣言方法を通じて、外部C/C++ファイルによって実現される。jvmは外部ライブラリをロードして対応する方法を見つけます。Java宣言が完了した後、javacを通じてヘッダファイルが生成され、JDK 10以前のバージョンであれば、javahを通じてヘッダファイルが生成され、
Javaコード C/C++Javaにアクセスすると、上のexampleから2つのパラメータがあります。このJNIEnvとjobjectはJavaの定義に対応する方法とメンバーのすべての情報を含んでいます。libjvm.soでJNI_を提供しました。CreateJavaVM関数はJNIEncvを初期化するために使われています。プロトタイプ 三、Rust JNI倉庫
Rust言語自体はC言語インターフェースを提供し、ffiの形で直接Cライブラリの関数を呼び出すことができます。文法はこうです。
#[link(so/filename)]
extern "C" {
fn foo() -> return_type;
}
#[repr(return_type)]
return type definition
JNIはJDKがJavaとC/C++の間で相互に呼び出すために提供しているもので、関数は全部libjvm.soに定義されています。Linuxシステムなら、実行します。locate libjvm.so
このライブラリが見つかります。2、Java Native Interface
JNIフルネームJava Native Interfaceは、JavaとC/C++の間の通信の仕組みを実現し、JavaからC/C++にアクセスでき、C/C++からJavaにアクセスすることもできます。
javac foo.java -h <header_dir>
関連するフィーチャーの更新記録はhttp://openjdk.java.net/projects/jdk/10/において、そのうち313条Remove the Native-Header Generation Tool (javah)
Hello World ExampleJavaコード
class HelloWorld {
private native void print();
public static void main(String[] args) {
new HelloWorld().print();
}
static {
System.loadLibrary("hello");
}
}
C言語コード#include
#include
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World
");
}
Makefile.PHONY: all clean tar
INC_DIR =
INC_DIR += -I/usr/lib/jvm/java-10-oracle/include/
INC_DIR += -I/usr/lib/jvm/java-10-oracle/include/linux
all: libhello.so
libhello.so: HelloWorld.o
gcc -shared -o $@ $<
%.o : %.c
gcc $(INC_DIR) -c -fPIC $<
clean:
@rm -rf libhello.so *.o
tar:
JNI_CreateJavaVM(JNIInvokeInterface **, JNINativeInterface **, JavaVMInitArgs *)
はJNIEnvを通じてJava中の方法とメンバーにアクセスできます。git clone https://github.com/benanders/rjni.git
cd rjni; cargo build
カードgo.tomlファイルにexampleを追加します。[[example]]
name = "instance"
path = "examples/instance.rs"
[[example]]
name = "field"
path = "examples/field.rs"
[[example]]
name = "static"
path = "examples/static.rs"
[[example]]
name = "static_field"
path = "examples/static_field.rs"
then use examples to test Rust JNI Crateexport LIBRARY_PATH=/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/; cargo run --example instance