JNI操作字符串简单的例子
一、编写StringObjectJava.java文件
class StringValue {
private String m_value;
private int m_byteLen;
StringValue() {
m_value = "empty";
m_byteLen = m_value.getBytes().length;
}
public String getValue() {
return m_value;
}
public void setValue(String value) {
m_value = value;
m_byteLen = value.getBytes().length;
}
int getByteLength() {
return m_byteLen;
}
}
public class StringObjectJava{
//所有native关键词修饰的都是对本地的声明
public native void setStringJni(StringValue obj);
static {
System.loadLibrary("test");//载入本地库
}
public static void main(String[] args) {
StringValue string_value_obj = new StringValue();
StringObjectJava obj = new StringObjectJava();
System.out.println("setStringJni before str = " + string_value_obj.getValue() + "\t bytelen = " + string_value_obj.getByteLength());
obj.setStringJni(string_value_obj);
System.out.println("setStringJni after str = " + string_value_obj.getValue() + "\t bytelen = " + string_value_obj.getByteLength());
}
}
二、执行javac命令
javac StringObjectJava.java
三、执行javah命令创建JNI头文件
(1) javah StringObjectJava
(2) mv StringObjectJava.h StringObjectJni.h
四、创建JNI实现文件
vi StringObjectJni.cpp
#include "StringObjectJni.h"
#include "iostream"
/* class: StringObjectJava
* Method: setStringJni
* Signature: (LStringValue;)V
*/
JNIEXPORT void JNICALL Java_StringObjectJava_setStringJni
(JNIEnv *env, jobject static_instance, jobject string_value_obj) {
std::cout << "hello Java_StringObjectJava_setStringJni implements C++"<< std::endl;
jclass cls = env->GetObjectClass(string_value_obj);
jmethodID function_id = env->GetMethodID(cls , "getValue" , "()Ljava/lang/String;");
jstring input_js = (jstring)env->CallObjectMethod(string_value_obj, function_id);
function_id = env->GetMethodID(cls , "getByteLength" , "()I");
jint input_len = env->CallIntMethod(string_value_obj,function_id);
const char* input_ptr = env->GetStringUTFChars(input_js,NULL);
std::cout << "java string_value_obj data :" << std::string(input_ptr,input_len)<<std::endl;
// Return value
std::string ret_val("hello world jni");
jstring ret_js_val = env->NewStringUTF(ret_val.c_str());
function_id = env->GetMethodID(cls , "setValue" , "(Ljava/lang/String;)V");
env->CallVoidMethod(string_value_obj, function_id,ret_js_val);
// 调用GetStringUTFChars函数必须释放资源,否则会内存泄漏。
env->ReleaseStringUTFChars(input_js,input_ptr);
// 调用NewStringUTF函数必须释放资源,否则内存泄漏。
env->DeleteLocalRef(ret_js_val);
}
五、编译动态链接库
(1) g++ -fPIC -I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/include/ -I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/include/Linux -c StringObjectJni.cpp
(2) g++ -shared -o libtest.so StringObjectJni.o
六、执行java类
java -Djava.library.path=. StringObjectJava