部分內容引用自網站:https://www.ibm.com/developerworks/cn/java/j-lo-cpp/index.html
GitHub: https://github.com/bytedeco/javacpp
如有侵權請聯繫筆者刪除
JavaCPP是一個開源庫,它提供了在 Java 中高效訪問本地 C++的方法。採用 JNI 技術實現,所以支持所有 Java 實現包括 Android 系統,Avian 和 RoboVM。
爲了調用本地方法,JavaCPP 生成了對應的 JNI 代碼,並且把這些代碼輸入到 C++編譯器,用來構建本地庫。使用了 Annotations 特性的 Java 代碼在運行時會自動調用 Loader.load() 方法從 Java 資源裏載入本地庫,這裏指的資源是工程構建過程中配置好的。
示例:
這是一個簡單的注入/讀出方法,類似於 JavaBean 的工作方式。清單 1 所示的 LegacyLibrary.h 包含了 C++類。
清單 1. LegacyLibrary.h
#include <string>
namespace LegacyLibrary {
class LegacyClass {
public:
const std::string& get_property() { return property; }
void set_property(const std::string& property) { this->property = property; }
std::string property;
};
}
接下來定義一個 Java 類,驅動 JavaCPP 來完成調用 C++代碼。
清單 2. LegacyLibrary.java
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include="LegacyLibrary.h")
@Namespace("LegacyLibrary")
public class LegacyLibrary {
public static class LegacyClass extends Pointer {
static { Loader.load(); }
public LegacyClass() { allocate(); }
private native void allocate();
// to call the getter and setter functions
public native @StdString String get_property(); public native void set_property(String property);
// to access the member variable directly
public native @StdString String property(); public native void property(String property);
}
public static void main(String[] args) {
// Pointer objects allocated in Java get deallocated once they become unreachable,
// but C++ destructors can still be called in a timely fashion with Pointer.deallocate()
LegacyClass l = new LegacyClass();
l.set_property("Hello World!");
System.out.println(l.property());
}
}
以上兩個類放在一個目錄下面,接下來運行一系列編譯指令,如清單 3 所示。
清單 3. 運行命令
$ javac -cp javacpp.jar LegacyLibrary.java
$ java -jar javacpp.jar LegacyLibrary
$ java -cp javacpp.jar LegacyLibrary
Hello World!
我們看到清單 3 最後運行輸出了一行“Hello World!”,這是 LegacyLibrary 類裏面定義好的,通過一個 setter 方法注入字符串,getter 方法讀出字符串。
上述內容都是引用自網站https://www.ibm.com/developerworks/cn/java/j-lo-cpp/index.html
光看別人的東西還是一知半解,所以筆者親自動手試了一下,發現總是生成不了dll文件,在這裏詳細記錄一下,僅供參考。歡迎各位討論
第一步:
參照上述內容創建 Legacylibrary.h LegacyLibrary.java文件並將其和 javacpp.jar 文件放在一個文件夾裏。
第二步:
打開VS的本機命令工具提示窗口(和Windows命令行窗口一樣),用次命令窗口進入到以上三個文件所在的文件夾目錄下,再用
$ javac -cp javacpp.jar LegacyLibrary.java
$ java -jar javacpp.jar LegacyLibrary
$ java -cp javacpp.jar LegacyLibrary
這三條命令去生成 dll 文件庫。
注意: 此處必須使用VS下的命令行進行操作,筆者此前使用Windows自帶命令行一直沒有成功,在執行第二條命令時會報“找不到指定文件”的錯誤。
VS下的命令行窗口啓動如下圖:
點擊打開文件夾並選擇對應的32位或64位工具。(打開命令行窗口時,若上方出現 Cannot determine the location of the VS Common Tools Folder,則需要在環境變量的 path中設置值:c:\windows\system32)
進入三個文件所在的文件夾及執行第一步編譯操作:
生成 dll 文件:
此時程序所在文件夾會生成一個子文件夾“windows-x86_64”,在此文件夾下會有生成的動態鏈接庫以及相關文件。
執行程序:
生成動態鏈接庫後將文件夾“windows-x86_64”整體粘貼到java項目下的 src 目錄下,並加載 javacpp.jar 包然後運行,顯示成功。