linux java JNI调用c 接口实例(包含void*和动态库 处理)

1,首先我要暴露的c接口为

void* pIpcCreateServer(int port);

void* pIpcCreateServer(int port);

2,根据我要暴露的接口编写了一个java 文件

java 文件test.java

public class test
{
static {
System.loadLibrary("test");  //链接库的名字
}
public native static void loadDll();
/*c interface return one void*, but here we change it to long*/
public native static long pIpcCreateServer(int port);
public native void pIpcCloseServer(long hdl);
public static void main( String[] args)
{
        test mytest = new test();
        mytest.loadDll();
        long hdl = mytest.pIpcCreateServer(8020);
        mytest.pIpcCloseServer(hdl);
}

 

3, 编译并生成test.h,这个文件是自动产生的,不要编辑他

javac test.java
javah -jni test

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class test */

#ifndef _Included_test
#define _Included_test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     test
 * Method:    loadDll
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_test_loadDll
  (JNIEnv *, jclass);

/*
 * Class:     test
 * Method:    pIpcCreateServer
 * Signature: (I)J
 */
JNIEXPORT jlong JNICALL Java_test_pIpcCreateServer
  (JNIEnv *, jclass, jint);

/*
 * Class:     test
 * Method:    pIpcCloseServer
 * Signature: (J)V
 */

JNIEXPORT void JNICALL Java_test_pIpcCloseServer
  (JNIEnv *, jobject, jlong);

#ifdef __cplusplus
}
#endif
#endif
 

4,根据test.h 编写对应的c文件 test.c

#include "test.h"
#include
/*
 void* pIpcCreateServer(int port);
recogRequest* pIpcReadMsg(void* hdl);//now  only for server 
void pIpcWriteMsg(void* request);
void pIpcCloseServer(void* hdl);
 * */
typedef void* (*pCreate) (int);
typedef void (*pClose)(void*);

pCreate pCreate_;
pClose pClose_;
JNIEXPORT void JNICALL Java_test_loadDll
  (JNIEnv *, jclass)
{
printf("start to load\n");
void* hdl = dlopen("libipc.so",RTLD_LAZY);
printf("hdl is %p\n",hdl);
pCreate_ = reinterpret_cast(dlsym(hdl, "pIpcCreateServer"));
pClose_ = reinterpret_cast(dlsym(hdl, "pIpcCloseServer"));
printf("create Sever handle %p\n",pCreate_);
}
JNIEXPORT jlong JNICALL Java_test_pIpcCreateServer
  (JNIEnv *, jclass, jint port)
{
jlong ret = 0;
void* hdl = pCreate_(port);
printf("hdl is %p\n", hdl);
ret = reinterpret_cast(hdl);
printf("ret is %ld\n", ret);
return ret;
}
JNIEXPORT void JNICALL Java_test_pIpcCloseServer
  (JNIEnv *, jobject, jlong hdl)
{
printf("hdl is %ld\n",hdl);
void* myhdl = reinterpret_cast(hdl);
printf("myhdl is %p\n",myhdl);
pClose_(myhdl);
}

编译:此处用到jni.h jni_md.h 所以有两个include 处理
g++ test.c -fPIC -shared -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.181-2.6.14.8.el7_5.x86_64/include/ -I/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.181-2.6.14.8.el7_5.x86_64/include/linux/ -o libtest.so

5,运行

java test

此处由于libipc.so涉及机密,不能上传,请自行模拟。

全文总结:本文由于c中有void* hdl,而在java中不方便转换,所以我们先转化为JNI的jlong结构。最后在使用handle时从一个jlong再转化成void*.

另外本文中java会调用libtest.so,而libtest.so中又调用libipc.so,避免了一些java和c的耦合。

 

版权声明:本文版权所有,欢迎转载,如需转载,请注明出处,谢谢合作!

 

 

你可能感兴趣的:(java)