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人點贊