1、编写native接口

package org.demo;

public class JniDemo
{
public static native int bmp2fea(byte[] bmp, byte[] fea, byte[] err); public static native int feaMatch(byte[] fea1, byte[] fea2, String flag, int level); }

2、根据native接口生成声明文件(.h)

javah -classpath . -jni org.demo.JniDemo

3、编写接口代码调动so动态库(.c)#include <stdlib.h>

#include <stadio.h>
#include <string.h>
#include 'org_demo_JniDemo.h' extern int feaMatch(char *pRegAscii, char *pVerAscii, int level);
extern int bmp2fea(unsigned char* bmp, char* feature, char* flag, char* errinfo); JNIEXPORT jint JNICALL JAVA_org_demo_JniDemo_bmp2fea (JNIEnv *env, jclass arg, jbyteArray bmp, jbyteArray fea, jbyteArray err)
{
char out[] = { };
char errinfo[] = { };
jbyte* pbmp = (*env)->GetByteArrayElements(env, bmp, );
jsize inSize = (*env)->GetArrayLength(env, bmp);
//bmp大小平均150k,使用malloc
//char *tmp = (char*)malloc(inSize + );
//memset(tmp, , inSize+);
  char *tmp = (char*)calloc(inSize+1, sizeOf(char));
  if (tmp == NULL)
  {
    (*env)->ThrowNew(env,
      (*env)->FindClass(env, "java/lang/OutOfMemoryError"), "jni calloc failed");
    return;
  }
memcpy(tmp, pbmp, inSize); int ret = bmp2fea((unsigned char*)tmp, (char*)out, (char*)errinfo);
if (ret == )
{
(*env)->SetByteArrayRegion(env, fea, , strlen(out), (jbyte*)out);
if (strlen(errinfo) > )
(*env)->SetByteArrayRegion(env, err, , strlen(errinfo), (jbyte*)out);
}
else
{
if (strlen(errinfo) > )
(*env)->SetByteArrayRegion(env, err, , strlen(errinfo), (jbyte*)out);
}
if (tmp != NULL)
{
free(tmp);
}
(*env)->ReleaseByteArrayElements(env, bmp, pbmp, JNI_ABORT);
return rt;
} JNIEXPORT jint JNICALL Java_org_demo_JniDemo_feaMatch (JNIEnv *env, jclass arg, jbyteArray fea1, jbyteArray fea2, jstring flag, jint level)
{
char tmp1[] = { };
char tmp2[] = { }; jbyte* pFea1 = (*env)->GetByteArrayElements(env, fea1, );
jsize inSize1 = (*env)->GetArrayLength(env, fea1);
memcpy(tmp1, pFea1, inSize1);
jbyte* pFea2 = (*env)->GetByteArrayElements(env, fea2, );
jsize inSize2 = (*env)->GetArrayLength(env, fea2);
memcpy(tmp2, pFea2, inSize2);
char* pflag = (char*)(*env)->GetStringUTFChars(env, flag, 0); 
int ret = feaMatch(tmp1, tmp2, pflag, level);
(*env)->ReleaseByteArrayElements(env, fea1, pFea1, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, fea1, pFea2, JNI_ABORT);
(*env)->ReleaseStringUTFChars(env, flag, pflag);
return ret;
}

4、根据.h、.c编译生成so,如下makefie文件make生成libengine.so

ODIR=.
EDIR=.
LDIR=.
INC_DIR=./ CC=g++
AR=ar -r
LD=ld
RM=rm -rf
cc=gcc
STRIP=strip
MKDIR=mkdir -p INCLUDES=-I$(INC_DIR)
CCFLAGS=-g $(INCLUDES) -fPIC
LIBS=-lc -ldl -ldemo SRC_DIR=./
ALL_DIR=-I$(SRC_DIR) -I/usr/java/jdk1..0_80/include/ -I/usr/java/jdk1..0_80/include/linux/ LIBAPI_SO=$(LDIR)/libengine.so
BIZD=$(EDIR)/test PROGRAM=$(LIBAPI_SO) ####object files####
LIBAPI_OBJ=$(ODIR)/org_demo_JniDemo.o
####object files####
BIZ_OBJ=$(ODIR)/test.o
##############
all:$(PROGRAM)
force:
$(LIBAPI_SO)::$(LIBAPI_OBJ)
@echo ----Linking...----
$(LD) -share -o $(LIBAPI_SO) $(LIBAPI_OBJ) -L./ $(LIBS)
@echo ----make $@ OK----
$(BIZD)::$(BIZ_OBJ)
@echo ----Linking...----
$(cc) -o $(BIZD) $(BIZD_OBJ) -L$(LDIR) $(LIBS) $(CCFLAGS)
@echo ----make $@ OK----
clean::
@$(RM) $(ODIR)/*.o $(PROGRAM)
cleanobj::
@$(RM) $(BIZ_OBJ)
cleanbin::
@$(RM) $(PROGRAM) .SUFFIXES:.cpp .c .o .so .a
####common#####
$(ODIR)/%.o:$(SRC_DIR)/%.c
$(cc) $(CCFLAGS) $< $(ALL_DIR) -c -o $@

5、java调用native接口

package org.demo;

import org.demo.JniDemo;

public class Demo
{
static {
// 动态库名: libdemo.so
System.loadLibrary("demo");
// libengine.so
System.loadLibrary("engine");
} public static int bmp2fea(byte[] bmp, byte[] fea, byte[] err)
{
return JniDemo.bmp2fea(bmp, fea, err);
} public static int feaMatch(byte[] fea1, byte[] fea2,String flag, int level)
{
return JniDemo.feaMatch(fea1, fea2, flag, level);
}
}

6、配置动态库路径

方法一:
#linux用户环境变量配置:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/demo/lib/ 方法二:
#程序启动是配置JVM参数:
java -Djava.library.path=/demo/lib/ -server -cp $CLASSPATH org.demo.Test

JNI调用so动态库的更多相关文章

  1. JNI_Android项目中调用.so动态库

    JNI_Android项目中调用.so动态库 2014年6月3日 JNI学习 參考:http://blog.sina.com.cn/s/blog_4298002e01013zk8.html 上一篇笔者 ...

  2. java使用JNA框架调用dll动态库

    这两天了解了一下java调用dll动态库的方法,总的有三种:JNI.JNA.JNative.其中JNA调用DLL是最方便的. ·JNI ·JNA ·JNative java使用 JNI来调用dll动态 ...

  3. c#调用c++动态库的一些理解

    调用c++动态库一般我们这样写   [DllImport("UCamer.dll", CallingConvention = CallingConvention.Winapi)] ...

  4. C#调用C++动态库(dll)

    在实际软件开发过程中,由于公司使用了多种语言开发,在C#中可能需要实现某个功能,而该功能可能用其他语言已经实现了,那么我们可以调用其他语言写好的模块吗?还有就是,由于C#开发好的项目,我们可以利用re ...

  5. C#总结(四)调用C++动态库

    由于公司很多底层的SDK,都是C++开发,上层的应用软件却是C# Winform程序.在实际工作的过程中,就经常碰到了C# 程序调用C++ 动态库的问题.最近一直在和C++ 打交道,C# 怎么调用C+ ...

  6. Java调用dll动态库

    最近项目里使用java调用dll动态库,因此研究了一下这方面的东西. 使用的工具包如下 <dependency> <groupId>net.java.dev.jna</g ...

  7. 【C#】 使用Gsof.Native 动态调用 C动态库

    [C#] 使用Gsof.Native 动态调用 C动态库 一.背景 使用C# 开发客户端时候,我们经常会调用一些标准的动态库或是C的类库.虽然C# 提供的PInvoke的方式,但因为使用的场景的多变, ...

  8. python调用.net动态库

    # python调用.net动态库 ### pythonnet简介------------------------------ pythonnet是cpython的扩展- pythonnet提供了cp ...

  9. Delphi XE7调用C++动态库出现乱码问题回顾

    事情源于有个客户需使用我们C++的中间件动态库来跟设备连接通讯,但是传入以及传出的字符串指针格式都不正确(出现乱码或是被截断),估计是字符编码的问题导致.以下是解决问题的过程: 我们C++中间件动态库 ...

随机推荐

  1. 洛谷 P5242 [USACO19FEB]Cow Dating P

    这道题很有意思. 不难发现,对于一个区间 \([l, r]\),恰好只有一个奶牛接受邀请的概率为 \[\prod_{i=l}^r(1-p_i) \cdot \sum_{i=l}^r \frac {p_ ...

  2. vue iviem UI grid布局

    Grid 栅格 概述 我们采用了24栅格系统,将区域进行24等分,这样可以轻松应对大部分布局问题.使用栅格系统进行网页布局,可以使页面排版美观.舒适. 我们定义了两个概念,行row和列col,具体使用 ...

  3. python的线性代数

    估计线性模型中的系数:a=np.linalg.lstsq(x,b),有b=a*x 求方阵的逆矩阵np.linalg.inv(A) 求广义逆矩阵:np.linalg.pinv(A) 求矩阵的行列式:np ...

  4. 《C Primer Plus(第6版)(中文版)》普拉达(作者)epub+mobi+azw3

    内容简介 <C Primer Plus(第6版)中文版>详细讲解了C语言的基本概念和编程技巧. <C Primer Plus(第6版)中文版>共17章.第1.2章介绍了C语言编 ...

  5. 5.6 Nginx Rewrite模块配置

  6. 六种方式实现hibernate查询,及IDE推荐

      这些天过的好乱,也许是因为考完试了,心里有些松懈吧.也许是最近发生的事对我有些触动吧.感觉自己都已经不懂自己了.面对一些人的教导,我很感激.因为很多话都对我有非常大的帮助和启发,也让我除了做技术, ...

  7. 设备树DTS 学习:2-设备树语法

    背景 通过上一讲了解完设备树DTS有关概念,我们这一讲就来基于设备树例程,学习设备树的语法规则. 参考:设备树详解dts.设备树语法详解.设备树使用总结 设备树框架 1个dts文件 + n个dtsi文 ...

  8. 快速为Eclipse配置PyDev插件

    想学习Python,查询网络之后发现PyDev是很好的插件,所以就想为Eclipse配置它.结果在整个配置的过程中出现了各种问题,版本问题,重复问题,反正乱七八糟的,本身安装一次的时间就很长,中间出现 ...

  9. An attempt was made to call the method com.google.gson.GsonBuilder.setLenient()Lcom/google/gson/GsonBuilder; but it does not exist. Its class, com.google.gson.GsonBuilder, is available from the foll

    SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/G:/sharp/repo ...

  10. idea 将部分class文件打包成jar使用

    工作中有时候有太多模块堆放一块比较混乱,将某个功能(例如:三方支付)所需要的模块打包成jar使用起来会方便点. 步骤如下: 选择 Empty,然后为自己打的jar起个名字 然后在myjar上面右键 创 ...