java-jna

注意

注意事项一:

数据类型:java 除了基本类型外其他对象都是引用例如 Double或者Personal per0

注意事项二:

思路:jna是从c接口往java接口推导,jni是从java接口往c推导

注意事项三:

崩溃经验:jna调用崩溃而c++调用没事的建议直接封可执行程序

注意事项四:

参数建议:有能力开发dll的话,如果遇到复杂的对象引用建议改为json字符串进行交互,极力建议

注意事项五:

用完释放:各个接口相互独立,之间没有关联关系,且涉及指针类型,在调用结束后立即释放指针内存

注意事项六:

风险规避:接口之间有调用顺序关系,且涉及指针类型,需要在开始新创建指针内存,结束后释放指针内存,否则可能会引起内存错误引用导致程序崩溃

注意事项七:

快速定位:前期开发阶段重视日志,可以快速定位分析解决问题,极力建议

jna调用会产生12字节内存碎片

pom引入

<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.5.0</version> </dependency>

工具

jna接口

public interface ImageJna extends Library { ImageJna INSTANTCE = Native.loadLibrary("CImageDetect", ImageJna.class); int getGDJLenth(String path); }

类型转换

方法 c++ java 特殊类型1 const char* String 特殊类型2 void*或char* Pointer 特殊类型3 void**或float** PointerByReference 基本类型(直接替换) double double 指针类型(使用ByReference) double* DoubleByReference 数组类型(使用Buffer) double[] DoubleBuffer

DoubleByReference用法

DoubleByReference dddaa1=new DoubleByReference(); dddaa1.setValue(10); double dddaa2=dddaa1.getValue(); System.out.println(dddaa2);

DoubleBuffer用法

DoubleBuffer ddd1=DoubleBuffer.allocate(10); for (int i=0;i<10;i++) ddd1.put(i*i); double[] dd= ddd1.array(); DoubleBuffer ddd2=DoubleBuffer.wrap(dd); System.out.println(Convert.toStr(ddd2.array())); double[] arg=new double[6]; arg[0] = 0; arg[1] = 180; arg[2] = 0; arg[3] = 180; arg[4] = 2; arg[5] = 2; double[] arg2=new double[]{0,180,0,180,2,2}; int arry0[] = {0, 8, 9, 6, 4}; int arry0Len = arry0.length;

Pointer用法

Pointer pointer = new Memory(256); //从指针里读 public void savePoint(String filename, Pointer pointer, int length) { byte[] bytes = new byte[length]; pointer.read(0, bytes, 0, length); saveFile(filename, bytes, length); } //往指针里写入 public void write(long bOff, byte[] buf, int index, int length,Pointer pointer) { pointer.write(bOff, buf, index, length); } per0[i].name=new Memory(per0[i].nameLen); String namestr="hhh"; per0[i].nameLen=namestr.length(); per0[i].name.setString(0,namestr);

jna手动释放内存

Pointer p = new Memory(1024 * 1024); long peer = Pointer.nativeValue(p); Native.free(peer);//手动释放内存 Pointer.nativeValue(p, 0);//避免Memory对象被GC时重复执行Nativ.free()方法 等同于c++ memoryFree

PointerByReference用法

***************************************** int len = oriVec_.size(); double* poriVec_ = new double[len]; double* pcalVec_ = new double[len]; double* perrVec_ = new double[len]; for (size_t i = 0; i < len; i++) { poriVec_[i] = oriVec_[i]; pcalVec_[i] = calVec_[i]; perrVec_[i] = errVec_[i]; } *oriVec__ = poriVec_; *calVec__ = pcalVec_; *errVec__ = perrVec_; *arryLen = len; ***************************************** PointerByReference buff1 = new PointerByReference(); PointerByReference buff2 = new PointerByReference(); PointerByReference buff3 = new PointerByReference(); double buffDouble1[] = buff1.getValue().getDoubleArray(0, buffLen.getValue()); double buffDouble2[] = buff2.getValue().getDoubleArray(0, buffLen.getValue()); double buffDouble3[] = buff3.getValue().getDoubleArray(0, buffLen.getValue()); HtQualityKernelLibrary.INSTANCE.releaseTwoPoint(buff1.getValue()); HtQualityKernelLibrary.INSTANCE.releaseTwoPoint(buff2.getValue()); HtQualityKernelLibrary.INSTANCE.releaseTwoPoint(buff3.getValue());

回调用法

***************************************** ISAR_QUALITY_DLLEXPORT typedef void(*calculateProcessFun)(double value); ***************************************** //定义 public interface ProcessCallback extends Callback { void process(double process); }; int simulatedPhotometricCalculationFileJna(String targetDir_, Callback callback); //使用 HtQualityKernelLibrary.ProcessCallback processCallback = new HtQualityKernelLibrary.ProcessCallback() { @Override public void process(double process) { log.info("process: "+process); } }; int ret = HtQualityKernelLibrary.INSTANCE.simulatedPhotometricCalculationFileJnaZhan(rootDir, processCallback);

char*转String

byte buffByte[] = buff.getValue().getByteArray(0, buffLen.getValue()); String jsonStr = new String(buffByte);

结构体

//结构体 int simpleStructTest1(Personal per0, Personal *per1); int simpleStructTest1(Personal.ByValue per0, Personal per1); IrsFaceRecogResultAll IrsFace=new IrsFaceRecogResultAll(); Pointer IrsFacepp1=IrsFace.getPointer(); IrsFace.age=111; IrsFace.write(); //结构体数组 int simpleStructTest3(Personal* per0, int per0Len, Personal *per1, int *per1Len); int simpleStructTest3(Personal[] per0, int per0Len, Personal[] per1, IntByReference per1Len); //demo int per0Len=5; Personal[] per0 = (Personal[])new Personal().toArray(per0Len); PointerByReference irsHandle = new PointerByReference(Pointer.NULL);

c语言导出宏

#ifdef USE_MINGW #define ISAR_QUALITY_DLLEXPORT #else #ifdef _WIN32 #ifdef COMPILE_LIB_QUALIOTY #define ISAR_QUALITY_DLLEXPORT extern "C" _declspec(dllexport) #else #define ISAR_QUALITY_DLLEXPORT extern "C" _declspec(dllimport) #endif // COMPILE_LIB_QUALIOTY #else #define ISAR_QUALITY_DLLEXPORT extern "C" __attribute__((visibility("default"))) #endif #endif

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值