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
pClose_ = reinterpret_cast
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
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
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的耦合。
版权声明:本文版权所有,欢迎转载,如需转载,请注明出处,谢谢合作!