目錄
一、過程
- 編寫C++動態庫並導出;
- 使用動態庫框架加載編寫的動態庫。
二、建立C++動態庫工程並編寫接口
(1)使用qt creator創建library庫程序,工程結構如下圖所示,具有三個.h頭文件,一個ctest.cpp類文件。
其中ctest_global.h爲工程自動生成,各文件功能描述如下:
文件名 | 功能 | 引用關係 |
ctest.h | 定義導出接口 |
引用ctestdata.h 引用ctest_global.h |
ctestdata.h | 定義數據結構體和方法的聲明 | |
ctest.cpp | 函數接口封裝類 | 引用ctest.h |
(2)ctest.h中,具有三個導出函數接口:求和、獲取手動結果、註冊回調。這三個函數接口都是我爲了測試怎樣調用和傳參杜撰的,沒有具體意義。ctest.h代碼如下所示:
#ifndef CTEST_H
#define CTEST_H
#include "ctest_global.h"
#include "ctestdata.h"
class CTESTSHARED_EXPORT CTest
{
public:
CTest();
};
#endif // CTEST_H
//導出結果
extern "C"{
//求和
int sum(int a,int b);
//獲取手動結果
int Target_Manual(FILETIME ftStartTime,FILETIME ftEndTime,Target* pTargets,int& nNum);
//註冊回調
int RegisterReceiveDataCallBack(ReceiveData func);
}
(3)ctestdata.h如下所示:
#ifndef CESTDATA_H
#define CESTDATA_H
#endif // CESTDATA_H
typedef unsigned long DWORD;
typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME;
struct Target
{
int nFrq;
FILETIME ftFindTime; //發現時間
float fLong; //經度
float fLat; //緯度
char szLoc[20]; //位置
Target()
{
}
};
//回調接口
typedef int ReceiveData(Target* pTarget,int nCount);
(4)導出類ctest.cpp
#include "ctest.h"
CTest::CTest()
{
}
Q_DECL_EXPORT int sum(int a, int b)
{
return a+b;
}
Q_DECL_EXPORT int Target_Manual(FILETIME ftStartTime,FILETIME ftEndTime,Target* pTargets,int& nNum)
{
return -1;
}
Q_DECL_EXPORT int RegisterReceiveDataCallBack(ReceiveData func)
{
return 0;
}
三、拷貝dll編寫java接口進行編譯
(1)在工程上鼠標右鍵單擊彈出編譯選項,依次執行qmake->構建即可生成dll庫,將dll庫拷貝至j動態庫加載框架的工程目錄resources/lib/windows目錄下
(2)編寫與調用庫匹配的函數接口
a.依照C++頭文件定義接構體類
b.依照C++頭文件定義如下java接口;
結構體類StruTarget:
package maoko.dllSolibLoad.lib.model.struct.meta;
import maoko.dllSolibLoad.lib.model.struct.JavaStructBase;
/**
* 目標信息
*
* @author fanpei
*
*/
public class StruTarget extends JavaStructBase {
public int nFrq;// 頻率
public StruFileTime.ByValue ftFindTime; // 時間
public float fLong; // 經度
public float fLat; // 緯度
public String szLoc; // 所屬地名
}
結構體類StruFileTime
package maoko.dllSolibLoad.lib.model.struct.meta;
import com.sun.jna.NativeLong;
import maoko.dllSolibLoad.lib.model.struct.JavaStructBase;
/**
* 時間信息
*
* @author fanpei
*
*/
public class StruFileTime extends JavaStructBase {
public NativeLong dwLowDateTime;// 開始時間
public NativeLong dwHighDateTime;// 結束時間
}
java接口ICTest
package maoko.dllSolibLoad.lib.load.ifs;
import com.sun.jna.Library;
import maoko.dllSolibLoad.lib.load.LibLoad;
import maoko.dllSolibLoad.lib.model.struct.meta.StruFileTime;
import maoko.dllSolibLoad.lib.model.struct.meta.StruTarget;
/**
* 加載動態庫接口
*
* @author fanpei
*
*/
@LibLoad(linuxName = "libCTest", windowsName = "CTest")
public interface ICTest extends Library {
/**
* 求和
*
* @param a 數據a
* @param b 數據b
* @return 返回兩數之和
*/
int sum(int a, int b);
/**
* 手動處理數據
*
* @param ftStartTime 開始時間
* @param ftEndTime 結束時間
* @param pTarget 待處理數組的地址
* @param nNum 待處理數組個數
* @return
*/
int Target_Manual(StruFileTime.ByValue ftStartTime, StruFileTime.ByValue ftEndTime, StruTarget.ByReference pTarget,
int nNum);
/**
* 註冊回調-用於異步返回數據
*
* @param func
* @return
*/
int RegisterReceiveDataCallBack(ICallBack func);
/**
* 回調接口
*
* @author fanpei
*
*/
public interface ICallBack {
/**
* 回調函數
*
* @param targets 結果數據
* @param nNum 結果個數
* @return
*/
public abstract int ReceiveCrossData(StruTarget.ByReference targets, int nNum);
}
}
設置JnaLibCall中的接口目錄靜態變量爲ICTest接口所在包名,如下圖所示:
最後運行框架,調用sum接口效果如下圖所示:
代碼完整地址:https://download.csdn.net/download/fanpei_moukoy/11195072