目录
JNA技术难点
有过跨平台、跨语言开发的程序员都知道,跨平台、预研调用的难点,就是不同语言之间数据类型不一致造成的问题。绝大部分跨平台调用的失败都是这个问题造成的。关于这一点,不论何种语言、何种技术方案都无法解决这个问题。JNA也不列外。
上面说到接口中使用的函数必须与链接库中的函数原型保持一致,这是JNA甚至所有跨平台调用的难点,因为C/C++的类型与Java的类型是不一样的,你必须转换成java对应类型让它们保持一致,这就是类型映射(Type Mappings),JNA官方给出的默认类型映射表如下:
其中类型映射的难点在于结构体、指针和函数回调。
1、函数回调
c++代码长这样:
// 实时监视接口
VIXHZ_EXPORT long _VixHz_StartRealPlay(
long lLoginID,
long lChannelNO,
int type,
HWND hWnd,
CallbackFuncRealDataEx func,
unsigned long dwUserParm);
// 回调函数
typedef bool (CALLBACK * CallbackFuncRealDataEx)(
unsigned long lRealHandle,
unsigned long dwDataType,
unsigned char *pBuffer,
unsigned long dwBufSize,
int width,
int height,
int ra,
unsigned long dwUser);
转java,在CLibrary接口中函数回调函数声明为RealDataCallbackListener接口:
/**
* 用于用户请求实时视频
*
* @param lLoginID 登录ID
* @param lChannelNO 通道号
* @param type 码流类型,1-主码流,2-辅码流
* @param hWnd 窗口句柄 传空指针即可
* @param realDataResult 实时数据回调函数
* @param dwUserParm 用户数据参数
* @return 请求成功返回此次会话session,错误返回错误码(<=0) {@link NetworkErrorEnum}
*/
NativeLong VixHz_StartRealPlay(NativeLong lLoginID, NativeLong lChannelNO, Integer type, Pointer hWnd, RealDataCallbackListener realDataResult, String dwUserParm);
RealDataCallbackListener接口:
package com.focus.vision.device.sdk.callback;
import com.sun.jna.Callback;
import com.sun.jna.NativeLong ;
import com.sun.jna.Pointer;
import org.springframework.stereotype.Component;
/**
* 回调函数声明接口
*/
@Component
public interface RealDataCallbackListener extends Callback {
/**
* 获取实时视频数据回调
*
* @param lRealHandle 播放句柄
* @param dwDataType 无实际意义
* @param pBuffer 实时数据
* @param dwBufSize
* @param dwUser 用户数据
* @return
*/
boolean getRealData(NativeLong lRealHandle, NativeLong dwDataType, Pointer pBuffer, NativeLong dwBufSize, String dwUser);
}
再在需要调用CLibrary.INSTANCE方法的类中,声明getVixHz_StartRealPlay:
/**
* 用户请求实时视频 回调函数
*
* @param lLoginID 登录ID
* @param lChannelNO 通道号
* @param type 码流类型,1-主码流,2-辅码流
* @param hWnd 窗口句柄 传空指针即可
* @param realDataResult 实时数据回调函数
* @param dwUserParm 用户数据参数
* @return
*/
public static boolean getVi