2023-02-02

C++、C#、Java調(diào)用C++ DLL

來源:http://www.itdecent.cn/p/a425b65a5db2

2020.01.04 16:34:07字?jǐn)?shù) 443閱讀 275

C++/C#/Java調(diào)用C/C++ DLL

[toc]

導(dǎo)出C++ Dll

C++ 編譯器為 VS2019

64 位 Debug 模式生成的無法調(diào)用(不知道具體原因)

MSVC++ 導(dǎo)出函數(shù)接口的方式主要有兩種:

_stdcall可以在項目屬性 -> C/C++ -> 高級 -> 調(diào)用約定處指定,就不用在每個函數(shù)前指定了

在函數(shù)定義時候加extern "C" _declspec(dllexport)

exportdll.h

extern"C"_declspec(dllexport)int_stdcallAdd(inti,intj);extern"C"_declspec(dllexport)float_stdcallAvg(inti,intj);

exportdll.cpp

#include"exportdll.h"intAdd(inti,intj){returni+j;}floatAvg(inti,intj){return(i+j)/2.0f;}

使用模塊定義文件(.def)聲明

exportdll.h

int_stdcallAdd(inti,intj);float_stdcallAvg(inti,intj);

exportdll.cpp

#include"exportdll.h"intAdd(inti,intj){returni+j;}floatAvg(inti,intj){return(i+j)/2.0f;}

右鍵源文件,選擇添加模塊定義文件exportdll.def

在項目屬性 -> 鏈接器 -> 輸入 -> 模塊定義文件處輸入exportdll.def

exportdll.def

LIBRARY exportdllEXPORTS? ? Add? ? Avg

簡單調(diào)用C++ DLL

均為基本數(shù)據(jù)類型的調(diào)用,復(fù)雜的數(shù)據(jù)類型會涉及到轉(zhuǎn)換對應(yīng)關(guān)系

C++動態(tài)調(diào)用

_stdcall也可以在項目屬性 -> C/C++ -> 高級 -> 調(diào)用約定處指定

第五行可能會出錯E0167 "const char *" 類型的實參與 "LPCWSTR" 類型的形參不兼容,項目屬性 -> 高級 -> 字符集選擇"使用多字節(jié)字符集”

intmain(){typedefint(_stdcall*AddFun)(int,int);typedeffloat(_stdcall*AvgFun)(int,int);HINSTANCE dll=LoadLibrary("exportdll.dll");if(dll!=NULL){AddFun Add=(AddFun)GetProcAddress(dll,"Add");if(Add!=NULL){cout<<Add(3,4)<<endl;}AvgFun Avg=(AvgFun)GetProcAddress(dll,"Avg");if(Avg!=NULL){cout<<Avg(3,4)<<endl;}}return0;}

C#調(diào)用

CallingConvention為StdCall可以不用指定

classProgram{[DllImport("exportdll.dll",CallingConvention=CallingConvention.StdCall)]externstaticpublicfloatAvg(intleft,intright);[DllImport("exportdll.dll"]externstaticprivateintAdd(intleft,intright);staticvoidMain(string[]args){Console.WriteLine(Avg(11,2));Console.WriteLine(Add(11,2));}}

Java調(diào)用

Java 調(diào)用 C++ 比較常用的方法有一下三種:

1. JNI

預(yù)先編譯好的 C++ dll 還需要進(jìn)一步使用jni封裝,較為麻煩,以后有機(jī)會再寫

2. JNative

DllImport.java

publicclassDllImport{publicstaticvoidmain(String[]args){JNativeadd=newJNative("exportdll.dll","Add");// 設(shè)置函數(shù)返回值為intadd.setRetVal(Type.INT);// add函數(shù)的第一個參數(shù)是3add.setParameter(0,3);// add函數(shù)的第二個參數(shù)是4add.setParameter(1,4);// 執(zhí)行add.invoke();// 獲取結(jié)果intresult=Integer.parseInt(add.getRetVal());//獲取返回結(jié)果System.out.println(result);}}

JNative 已經(jīng)很久沒有更新了,上一次更新是 2013-04-26

3. JNA

pom.xml

<dependency><groupId>com.sun.jna</groupId><artifactId>jna</artifactId><version>3.0.9</version></dependency>

DllLibrary.java

publicinterfaceDllLibraryextendsLibrary{intAdd(inti,intj);floatAvg(inti,intj);}

DllImport.java

publicclassDllImport{publicstaticvoidmain(String[]args){DllLibrarydll=(DllLibrary)Native.loadLibrary("exportdll.dll",DllLibrary.class);System.out.println(dll.Add(3,4));System.out.println(dll.Avg(3,4));}}

小結(jié)

哪有什么歲月靜好,不過是有人替你負(fù)重前行;以上三種方法語法越簡單的就意味著性能越差,畢竟有很多中間商在替你負(fù)重前行。

性能:JNI > JNative >> JNA

0人點贊

CXX

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容