簡體   English   中英

帶有外部庫的Java JNI'C'代碼

[英]Java JNI 'C' code with external libraries

我已經按照本指南從Linux上的NetBeans IDE和C / C ++插件開始使用JNI來運行Java應用程序中的“ C”代碼,並且一切正常。

我的問題是,當我嘗試使用外部庫(例如amqp.h)時,出現錯誤:

符號查找錯誤:/home/amir/NetBeansProjects/c_pcap_parser/lib/c_pcap_parser.so:未定義符號:amqp_new_connection Java結果:127

如何在我的最終.so文件中包含這些庫?

首先,您應該對平台上的本機庫有基本的了解。 有靜態和動態庫。

靜態意味着將所有本機代碼添加到庫文件中以供重用。 因此,如果您已經編譯了一些C代碼,您將了解* .o文件,其中包含您的處理器可以理解的二進制代碼。 靜態庫只是它們的集合。 在Linux平台上,它們通常具有文件擴展名.a。 鏈接到靜態庫時,所有本機二進制代碼都將添加到您的應用程序中(比方說您的可執行文件)。

相反,動態庫不會物理地添加到您的可執行文件中,如果需要,可以從全局系統目錄中進行引用(這與PATH環境類似)。 它們在Linux上稱為共享對象(擴展名.so)。 還有對於環境變量在大多數平台上,我認為這是所謂的LD_LIBRARY_PATH (見為destinction堆棧溢出)。 將在環境變量的所有目錄中搜索可以在啟動時鏈接到您的應用程序的共享對象。

考慮到這一點,您可以嘗試解決問題。 我想amqp.h屬於C Rabbitmq客戶端 如果要在Java中使用該C代碼,則需要首先在平台上對其進行編譯。 這是通過遵循我上面引用的github項目頁面上的描述來完成的。

好的,在成功的構建過程之后,您將從編譯中獲得一些庫文件,我認為他們將創建一個動態庫,但是我不確定。 該結果的結果決定了您對Java代碼的操作。 如果它是動態庫,將共享對象添加到java本機庫路徑就足夠了。 您參考的教程中也顯示了此內容。 我只是為Rabbitmq C庫的潛在共享對象添加了一個條目:

static {
    System.load("full-path-to-NetBeansProjects-dir/JNIDemoCdl/dist/libJNIDemoCdl.so");
    System.load("full-path-to-dir-where-the-rabbitmq-so-lives-in/librabbitmq.so");   
}

如果它將是靜態庫,則實際上您需要對此有所不同。 您需要在C編譯期間鏈接librabbitmq.a庫,以正確進行連接。 在您的問題中引用的教程中,我看到Netbeans為C編譯器提供了一個鏈接器部分,其中您可以在C編譯期間添加Rabbitmq的靜態庫。

一個免責聲明:如果您只想使用Java代碼訪問Rabbitmq,那么當然還會退出一個Java庫 ,該應該與Rabbitmq一起使用要容易得多(您不需要整個JNI和C編譯的東西)。

還要注意問題中給定教程的內容:它們使用-m32標志編譯C代碼,該標志生成32位共享對象。 如果您按照我上面的說明進行操作,則可能會出現問題! 原因是您還需要使用此標志將rabbitmq C客戶端編譯為32位。 大多數平台上的默認gcc編譯器將生成64位庫,該庫與32位JVM和32位共享庫不兼容。 因此,請確保全部為32位或64位,但無論如何不要混在一起! 例如,生活在具有64位JVM的64位計算機上,必須刪除-m32標志。

暫無
暫無

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

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