java調用動態庫dll/so(四)動態庫加載框架的使用舉例

目錄

一、過程

二、建立C++動態庫工程並編寫接口

三、拷貝dll編寫java接口進行編譯


一、過程

  1. 編寫C++動態庫並導出;
  2. 使用動態庫框架加載編寫的動態庫。

二、建立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

                         https://github.com/maokofan/maoko.dllSoLibLoad

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章