JNI:在c代码中获得和直接修改java的string成员变量的值

jni c和java交互中,大部分数据类型都有对应,java中的string类型比较特殊,所以要用object。
java代码 StringTest1.java


public class StringTest1    {
    public String s = new String("java string");
    //声明c方法
    public native void displayHelloWorld();

    static{
        //加载库名
        System.loadLibrary("StringTest1");
        }
    public static void main(String[] args){ 
        StringTest1 st1 = new StringTest1();
        System.out.println("before call c:");   
        System.out.println(st1.s);
        st1.displayHelloWorld();
        System.out.println("after call c:");    
        System.out.println(st1.s);
        }

    }

命令行输入:
java StringTest1.java 生成StringTest1.java
javah StringTest1 生成StringTest1.h
可以查看StringTest1.h文件,了解C中方法名

JNIEXPORT void JNICALL Java_StringTest1_displayHelloWorld
  (JNIEnv *, jobject);

c代码 StringTest1.c
java int 类型 c中可以用int对应,GetIntFIeld()等
java的String类型 c中无对应类型,用object对应,如GetObjectField();

#include <jni.h>
#include "StringTest1.h"
#include <stdio.h>

JNIEXPORT void JNICALL

Java_StringTest1_displayHelloWorld(JNIEnv *env,jobject obj){
//得到java类名
    jclass java_class = (*env)->GetObjectClass(env,obj);
//string的类型签名有个分号;
    jfieldID id_str = (*env)->GetFieldID(env,java_class,"s","Ljava/lang/String;");
/* //中间注释掉的这部分是c获得java的字符串
//强制类型转换,jobject转换为jstring
    jstring str = (jstring)(*env)->GetObjectField(env,obj,id_str);
    jsize len = (*env)->GetStringLength(env,str);
    jchar j2c[len+1];
    j2c[len] = L'\0';
//字符串str内容复制给j2c字符数组
    (*env)->GetStringRegion(env,str,0,len,j2c);
*/
//以下实现 c修改java的string成员变量值
    char* c2j = "c print string";
//字符数组c2j转换成jstring类型   
    jstring cstr = (*env)->NewStringUTF(env,c2j);
//设置java的string类型变量s的值
    (*env)->SetObjectField(env,obj,id_str,cstr);
    }

编译c文件
gcc -I/usr/java/jdk1.7.0_79/include/ -I/usr/java/jdk1.7.0_79/include/linux -shared -o libStringTest1.so StringTest1.c
(1)需要jni.h和jni_md.h文件,所以加入-I/jdk路径/include和-I/jdk路径/include/linux
(2)-fPIC -shared -o 第一个可选,我没写,没遇到问题
java StringTest1
结果
before call c:
java string
after call c:
c print string

小技巧
1.java -s -p StringTest1 (包名.类名),得到每个方法的签名
Compiled from “StringTest1.java”
public class StringTest1 {
public java.lang.String s;
Signature: Ljava/lang/String;
public StringTest1();
Signature: ()V

public native void displayHelloWorld();
Signature: ()V

public static void main(java.lang.String[]);
Signature: ([Ljava/lang/String;)V

static {};
Signature: ()V
}
2. 查看你的jdk1.7/include/jni.h (第一个文件夹名字根据自己的版本具体名字)jni.h文件中有各个JNI方法的格式

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值