JNI实现Java调用C++

一、展示基本流程的简单例子

1、Java封装程序MyNative.java

public class MyNative
{
static
{
System.loadLibrary( "MyNative" );
}
public native static void HelloWord();
public native static String cToJava(byte[] para);
}

javac MyNative.java 编译

javah MyNative 生成c头MyNative.h

* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyNative */

#ifndef _Included_MyNative
#define _Included_MyNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     MyNative
 * Method:    HelloWord
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_MyNative_HelloWord
  (JNIEnv *, jclass);

/*
 * Class:     MyNative
 * Method:    cToJava
 * Signature: ([B)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_MyNative_cToJava
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

2、c实现文件MyNative.cpp
#include "MyNative.h"
JNIEXPORT void JNICALL Java_MyNative_HelloWord (JNIEnv *env, jclass jobject)
{
printf("hello word!/n");
}
JNIEXPORT jstring JNICALL Java_MyNative_cToJava(JNIEnv *env, jclass obj)
{
jstring jstr;
char str[]="Hello,word!/n";
jstr=env->NewStringUTF(str);
return jstr;
}

g++ -shared -o libMyNative.so MyNative.cpp  -I/usr/lib/jdk1.6.0_04/include/ -I/usr/lib/jdk1.6.0_04/include/linux 编译
注意:在Linux下编译时需要包含linux子目录,否则会提示“jni_md.h:No such file or directory”
注意:-o文件名记住包含lib前缀,并保证libMyNative.so放置在LD_LIBRARY_PATH

3、测试java程序
public class mytest
{
public static void main(String[] args)
{
MyNative a=new MyNative();
a.HelloWord();
System.out.println(a.cToJava());
}
}

javac mytest.java 编译
java mytest运行

二、考虑参数传递
1、Java封装程序MyNative.java

public class MyNative
{
static
{
System.loadLibrary( "MyNative" );
}
public native static String cToJava(byte[] arrayvalue, int intvalue, String strvalue);
}


javac MyNative.java 编译

javah MyNative 生成c头MyNative.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyNative */

#ifndef _Included_MyNative
#define _Included_MyNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     MyNative
 * Method:    cToJava
 * Signature: ([BILjava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_MyNative_cToJava
  (JNIEnv *, jclass, jbyteArray, jint, jstring);

#ifdef __cplusplus
}
#endif
#endif


2、c实现文件MyNative.cpp
#include <alloca.h>
#include <string.h>
#include "MyNative.h"

JNIEXPORT jstring JNICALL Java_MyNative_cToJava (JNIEnv *env, jclass jobject, jbyteArray arrayvalue, jint intvalue, jstring strvalue)
{
jsize theArrayLengthJ = env->GetArrayLength(arrayvalue);
jbyte * arrayBody = env->GetByteArrayElements(arrayvalue,0);
char *str = (char *) alloca(sizeof(jbyte)*theArrayLengthJ +1);
memcpy(str, arrayBody, sizeof(jbyte)*theArrayLengthJ);
str[sizeof(jbyte)*theArrayLengthJ] = 0x0;

const char* str2 = env->GetStringUTFChars(strvalue, 0);
printf("Parameter/n charArray: [%s]/n int: [%d] /n String: [%s] /n", str, intvalue, str2);

jstring jstr;
char ret[]="Success!/n";
jstr=env->NewStringUTF(ret);
return jstr;
}
注意:int,byte等基本类型可以直接用,但是Array,String类型需要调用Getxxx方法转化为C类型。

g++ -shared -o libMyNative.so MyNative.cpp  -I/usr/lib/jdk1.6.0_04/include/ -I/usr/lib/jdk1.6.0_04/include/linux 编译


3、测试java程序
public class mytest
{
public static void main(String[] args)
{
MyNative a=new MyNative();
String test = "parameter";
byte[] para = test.getBytes();
String ret = a.cToJava(para, 1, test);
System.out.print("Function return ");
System.out.println(ret);
}
}


javac mytest.java 编译
java mytest运行

三、补充说明
前两个例子中的cpp程序都没做什么事情,实际的用法是在该cpp中调用其他C++来中已实现的方法。

另外,如果是要将java程序放在包中,则编译和运行方法会有所差异。假设package名为mytest,则
编译javac mytest/MyNative.java
生成头文件javah mytest.MyNative
生成的头文件函数名会包含mytest

本文参考若干网络资料而成,不一一列举,再次感谢。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值