JNI访问C端struct

本文介绍了如何通过JNI从Java程序中直接访问并操作C语言的struct,详细讲解了从定义C数据结构、创建Java访问接口,到生成头文件、定义C方法、编译动态链接库,最后在Java中执行的过程。示例中着重展示了数据交互,但并未涉及内存管理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里解决的问题是把C的struct传给Java,并读写其中的内容。仅仅是读写C的struct,不需要把C的数据结构映射到java。

注:仅是一个通路,未考虑内存管理。

定义C的数据结构

c_demo.h

typedef struct testStruct {
int id;
char* name;
} testStruct;

定义Java的访问接口

JNIDemo.java

public class JNIDemo {

    static {
        System.loadLibrary("c_demo");   // load c library
    }

    /* Program entry function */
    public static void main(String args[]) {

        // New a C struct, and get pointer as handle
        long handle = create();
        System.out.println(handle); //print the pointer

        // Set ID field  to 99
        setID(handle, 99);
        int new_id = getID(handle);
        System.out.println(new_id); //print ID setted

        // Set NAME field
        setName(handle, "asdfBB");
        String new_name = getName(handle);
        System.out.println(new_name); //print NAME field
    }

    /* define java native method */

    public native static long create();

    public native static int getID(long handle);

    public native static String getName(long handle);

    public native static void setID(long handle, int a);

    public native static void setName(long handle, String a);

}

编译Java

javac JNIDemo.java

生成h文件

javah JNIDemo

定义C方法

#include <stdlib.h>
#include "jni.h" 
#include "c_demo.h"


JNIEXPORT jlong JNICALL Java_JNIDemo_create
  (JNIEnv *env, jobject cls)
{
  testStruct *t = malloc(sizeof(testStruct));
  t->id = 0;
  t->name = NULL;
  return (jlong)t;
}

JNIEXPORT jint JNICALL Java_JNIDemo_getID
  (JNIEnv *env, jobject cls, jlong handle)
{
  testStruct *t =  (testStruct*)handle;
  return t->id;
}

JNIEXPORT jstring JNICALL Java_JNIDemo_getName
  (JNIEnv *env, jobject cls, jlong handle)
{
  testStruct *t =  (testStruct*)handle;
  return (*env)->NewStringUTF(env, t->name);
}

JNIEXPORT void JNICALL Java_JNIDemo_setID
  (JNIEnv *env, jobject cls, jlong handle, jint a)
{
  testStruct *t =  (testStruct*)handle;
t->id = a;
}

JNIEXPORT void JNICALL Java_JNIDemo_setName
  (JNIEnv *env, jobject cls, jlong handle, jstring a)
{
  testStruct *t =  (testStruct*)handle;
  char * c_str = (*env)->GetStringUTFChars(env, a, NULL);
  t->name = c_str;
}

编译so

注意需要指定jni.h的目录。

gcc -shared -o libc_demo.so c_demo.c -I ../include -I ../include/linux -fPIC

执行Java

export LD_LIBRARY_PATH=.
java JNIDemo

结果

140483147157408
99
asdfBB

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值