搜尋
首頁Javajava教程Java如何利用jna呼叫c#中dll的範例

Java如何利用jna呼叫c#中dll的範例

Sep 08, 2017 am 10:53 AM
.netjava

前一段時間接了個項目,需要用到第三方提供的C#編寫的dll,本身項目是java語言,所以便有了下面這篇文章,本文給大家介紹了關於java中如何使用jna調用c#中dll的相關資料,文中透過範例程式碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

JNA(Java Native Access )提供一組Java工具類別用於在運行期間動態存取系統本機程式庫(native library :如Window的dll)而不需要寫任何Native/JNI程式碼。開發人員只要在一個java介面中描述目標native library的函數與結構,JNA就會自動實作Java介面到native function的對應。

優點

JNA可以讓你像呼叫一般java方法一樣直接呼叫本地方法。就跟直接執行本地方法差不多,而且呼叫本地方法還不用額外的其他處理或配置什麼的,也不需要多餘的引用或編碼,使用很方便。 JNA最大的好處是避免了重複造輪子的浪費時間的行為.

用過JNI的大神都知道,JNI是一種很變態的設計,JNI需要導入專門為Java生成的頭檔,是一種侵入式的設計,這樣被強行改造的源碼編譯的dll將不能被C#調用

#JNA描述

JNA類別庫使用一個很小的本地類別庫sub 動態的呼叫本地程式碼。程式設計師只需要使用一個特定的java介面來描述一下將要呼叫的本地程式碼的方法的結構和一些基本屬性。這樣就省了為了適配多個平台而大量的配置和編譯程式碼。因為呼叫的都是JNA提供的公用jar 套件中的介面。

一、需求闡述:

如果我們的專案利用c#開發,到了開發後期需要和java群組合作,其中有一部分業務邏輯利用c#已經code completed,那麼我們可能會考慮用java來呼叫現成的c#dll實作需求。前幾天工作上正好遇到這樣一個問題,於是記下開發過程。

當然這只是個假設,具體情況具體分析,個人認為重構程式碼才是王道…

二、原理說明:

#其實具體原理我也沒弄太明白,我就根據自己的理解來說吧,拋磚引玉。

因為c#程式碼是託管到.net平台上的,所以java不能直接呼叫c#程式碼,於是引入C++中間件,c++專案可以設定專案為clr公共運行時,從而透過引用的方式呼叫c#相應方法。而jna是可以直接呼叫c++產生的dll的,於是大致流程就走通了。 c++呼叫寫好的c#dll,java再呼叫c++產生的dll中間件,大致流程就是這樣了,不過其中有很多坑,下面我會細說。

三、運行平台:

  系統:Windows 10 x64

  開發工具:Visual Studio 2015/2017(我筆記型電腦和公司電腦安裝不同版本,我都有實現過) MyEclipse2014

  SDK:jdk-x86、jdk-x64 (dll分為x86和x64平台,和jdk的版本要對應,同一台電腦裝兩個版本的jdk比較煩,我採用的是系統配置jdk32位調試32位dll,然後myeclipse自帶64位jdk調試64位dll)

四、準備工作:

  1、先準備上述運作平台,建議選擇和系統位數一致的jdk(安裝vs、myeclipse或eclipse或sts);

  2、下載jna.jar :JNA下載  (下載jna-4.4.0.jar 和jna-platform-4.4.0),也可以本地下載

五、開始CODE

5.1 產生c#DLL

  5.1.1 以管理員方式啟動vs(專案涉及到註冊com元件,必須以管理員啟動才能完成),新建c#項目

 

  5.1.2 設定c#項目

    首先,右鍵剛剛新建的Invoke項目,點選屬性。

繼續設定專案屬性。

############記得儲存。 ######然後新建需要被呼叫的CSharp類別程式碼。這裡我們新建一些簡單的方法,為了示範效果我們分別對int、string、bool進行操作。如圖:###############然後右鍵項目,點選生成。 ###############第一步,完成,做得漂亮。 #########5.2 產生c++中間件#######

       

新專案。項目,選擇屬性。

  

  5.2.2 書寫c++代碼

添加cpp文件

      

      

編輯cpp檔

好了,c++和c#全部工作完成,右鍵產生。

複製下dll產生檔案全名,一會兒java裡面用。

六、寫java程式碼

6.1 新建java project ,注意選擇和dll平台一致的jdk。然後將先前下載的兩個jna的jar載入到專案裡面,如圖:

#6.2 開始寫java 程式碼

然後我們運行:

哦豁,報錯了【無效的記憶體存取】,因為java找到了c++dll,但沒找到c#的dll,其中c++dll我們寫的全路徑名,可以直接找到,那c#的dll怎麼找呢。答案是將c#的dll複製到jdk的bin目錄下,jvm就能找到了。

如圖我們將Invoke.dll複製到jdk的bin目錄下:

  

然後再運行:    

nice!對於常用類型中的int、string、boolean都可以順利傳遞了,事實上其他類型的也可以實現,只要遵循不同語言之間的類型對應關係就可以了,具體的類型關係可以百度。

七、注意事項

7.1 java報錯:Exception in thread "main" java.lang.Error: Invalid memory access

可能原因:

  1、c#dll沒有複製到jdk的bin目錄;

  2、java和c++之間資料類型不對應;

  7.1.2 java報錯:Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'D:\vs workplace\X86InvokeTest\Release\X86CPPDlls': Nativelibrary (632 \vs workplace\X86InvokeTest\Release\X86CPPDlls.dll) not found in resource path ([file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/bin/, file:/Goke:0%20Ec/plip Lib/jna-4.4.0.jar, file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-platform-4.4.0.jar])

可能原因:

  1、c++dll路徑不正確,建議做test時用絕對路徑,這樣你在c++專案編譯過後不用拷貝便可以在java程式裡面直接呼叫;  2、jdk的平台和c++專案的平台不匹配,jdk是32位元那麼c++dll一定也是32位的,64位元也同樣;

  7.1.3 windows64位元下編譯的32位元dll測試失敗,暫時不清楚是不是64位元系統的原因,由於我電腦虛擬機沒有裝上,就沒有去32位元系統上測試了。 ############總結##########

以上是Java如何利用jna呼叫c#中dll的範例的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
是否有任何威脅或增強Java平台獨立性的新興技術?是否有任何威脅或增強Java平台獨立性的新興技術?Apr 24, 2025 am 12:11 AM

新興技術對Java的平台獨立性既有威脅也有增強。 1)雲計算和容器化技術如Docker增強了Java的平台獨立性,但需要優化以適應不同雲環境。 2)WebAssembly通過GraalVM編譯Java代碼,擴展了其平台獨立性,但需與其他語言競爭性能。

JVM的實現是什麼,它們都提供了相同的平台獨立性?JVM的實現是什麼,它們都提供了相同的平台獨立性?Apr 24, 2025 am 12:10 AM

不同JVM實現都能提供平台獨立性,但表現略有不同。 1.OracleHotSpot和OpenJDKJVM在平台獨立性上表現相似,但OpenJDK可能需額外配置。 2.IBMJ9JVM在特定操作系統上表現優化。 3.GraalVM支持多語言,需額外配置。 4.AzulZingJVM需特定平台調整。

平台獨立性如何降低發展成本和時間?平台獨立性如何降低發展成本和時間?Apr 24, 2025 am 12:08 AM

平台獨立性通過在多種操作系統上運行同一套代碼,降低開發成本和縮短開發時間。具體表現為:1.減少開發時間,只需維護一套代碼;2.降低維護成本,統一測試流程;3.快速迭代和團隊協作,簡化部署過程。

Java的平台獨立性如何促進代碼重用?Java的平台獨立性如何促進代碼重用?Apr 24, 2025 am 12:05 AM

Java'splatformindependencefacilitatescodereusebyallowingbytecodetorunonanyplatformwithaJVM.1)Developerscanwritecodeonceforconsistentbehavioracrossplatforms.2)Maintenanceisreducedascodedoesn'tneedrewriting.3)Librariesandframeworkscanbesharedacrossproj

您如何在Java應用程序中對平台特定問題進行故障排除?您如何在Java應用程序中對平台特定問題進行故障排除?Apr 24, 2025 am 12:04 AM

要解決Java應用程序中的平台特定問題,可以採取以下步驟:1.使用Java的System類查看系統屬性以了解運行環境。 2.利用File類或java.nio.file包處理文件路徑。 3.根據操作系統條件加載本地庫。 4.使用VisualVM或JProfiler優化跨平台性能。 5.通過Docker容器化確保測試環境與生產環境一致。 6.利用GitHubActions在多個平台上進行自動化測試。這些方法有助於有效地解決Java應用程序中的平台特定問題。

JVM中的類加載程序子系統如何促進平台獨立性?JVM中的類加載程序子系統如何促進平台獨立性?Apr 23, 2025 am 12:14 AM

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器會產生特定於平台的代碼嗎?解釋。Java編譯器會產生特定於平台的代碼嗎?解釋。Apr 23, 2025 am 12:09 AM

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

JVM如何處理不同操作系統的多線程?JVM如何處理不同操作系統的多線程?Apr 23, 2025 am 12:07 AM

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用