我想從Java調用Rust庫,我真的想用SWIG從我編寫的C頭文件生成接口層(我也想讓普通的C客戶端調用我的庫,因此我認爲維護一個接口頭是有意義的)。是否可以一起使用Java,SWIG和Rust?
我在Windows上使用Mingw和Rust (GNU ABI)來做這件事。
我會進入到我所做的和下面的結果,但基本上我得到了最後的UnsatisfiedLinkError。有幾件事我認爲可能是錯誤的,但我不確定如何(或如果)我可以修復它們:
- SWIG將數字放在函數名稱中(您可以看到這個如果你編輯它在我的例子中產生的
testlib_wrap.c
文件)。 - JNI documentation說我編譯時需要通過參數
-Wl,--add-stdcall-alias
,但是因爲我正在建造貨物,所以我不知道該怎麼做(如果我直接用rustc構建,我可以通過它嗎?我什麼都看不到在man page)
所以,總之,我的問題是:
你如何使用痛飲從Java調用到鏽?
但是我覺得我正在抓一個解決方案的表面,所以答案可能是解決上面的一個或兩個問題,所以這裏就是我到目前爲止......
我開始通過使使用Cargo新鏽庫:
cargo new testlib
cd testlib
與內容創建testlib.h
:
void tell_me_the_answer(void);
創建了一大口輸入文件(testlib.i
)包含以下內容:
%module testlib
%{
#include "testlib.h"
%}
%include "testlib.h"
運行痛飲生成一些Java和C:
mkdir testlib
swig -outdir testlib -java -package testlib testlib.i
創建一個主要的Java類(Program.java
)與內容:
public final class Program {
static {
System.loadLibrary("testlib");
}
public static void main(final String[] args) {
testlib.testlib.tell_me_the_answer();
}
}
編譯java:
javac Program.java testlib\testlib.java testlib\testlibJNI.java
編輯貨物製作的src\lib.rs
文件實現功能:
#[no_mangle]
pub extern "C" fn tell_me_the_answer() {
println!("The answer is...APPLES!");
}
創建一個新的build.rs
文件通過gcc-rs庫,其中包含編譯痛飲輸出掛鉤:
extern crate gcc;
fn main() {
gcc::Config::new()
.file("testlib_wrap.c")
.include("C:/Program Files/Java/jdk1.8.0_45/include")
.include("C:/Program Files/Java/jdk1.8.0_45/include/win32")
.compile("libtestlib.a");
}
編輯Cargo.toml
文件,它包含:
[package]
name = "testlib"
version = "0.1.0"
build = "build.rs"
[lib]
name = "testlib"
crate-type = ["dylib"]
[build-dependencies]
gcc = "0.3"
編譯防鏽工程:
cargo build
運行Java應用程序:
java -Djava.library.path=target\debug Program
收到以下錯誤:
Exception in thread "main" java.lang.UnsatisfiedLinkError: testlib.testlibJNI.tell_me_the_answer()V
at testlib.testlibJNI.tell_me_the_answer(Native Method)
at testlib.testlib.tell_me_the_answer(testlib.java:13)
at Program.main(Program.java:6)
我看了一下這貨讓我在dependency walker的DLL,它看起來有點空(在條款的這出口)和單一的功能看起來有點奇怪,至少對我來說,由於名稱@部分,我認爲--add-stdcall-alias
將刪除權利?
上午我關閉,並在DLL的名稱所示的Dependency Walker是我的問題的根源在哪裏?
如果是Java_testlib_testlibJNI_tell_me_the_answer
它會起作用嗎?
如果是這樣,我該如何做到這一點(我編輯_wrap.c
SWIG產生的文件刪除1,但我不知道我將如何擺脫@)?
如果不是,問題是什麼?