当前位置: 首页 > news >正文

c语言jni实战,双系统

1.首次编写jni接口代码,需要安装java

#centos ,我使用的centos,其他系统安装方式不同。

sudo yum update -y

sudo yum install java-11-openjdk-devel -y

java -version  

#输出版本类似

#openjdk version "1.8.0_292"

#OpenJDK Runtime Environment (build 1.8.0_292-b10)

#OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)

vi /etc/profile.d/java.sh

增加

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk

export JRE_HOME=$JAVA_HOME/lib

export PATH=$JAVA_HOME/bin:$PATH

#windows

①安装jdk,去java官网下载,这里使用版本jdk-23_windows-x64_bin.exe

②安装完毕后设置环境变量

新建系统变量 JAVA_HOME:C:\Program Files\Java\jdk-23

是你jdk的安装路径,默认是这个

③在环境变量的PATH中新增 %JAVA_HOME%\bin

④重启计算机或visual studio

2.配置jni环境变量(linux接第一步)

find /usr/lib/jvm -name jni.h

#/usr/lib/jvm/java-11-openjdk-11.0.23.0.9-2.el7_9.x86_64

vi ~/.bashrc

#在末尾加入

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.23.0.9-2.el7_9.x86_64

export C_INCLUDE_PATH=$JAVA_HOME/include:$JAVA_HOME/include/linux:$C_INCLUDE_PATH

保存后重启机器

LinuxMakefile

# JDK 安装路径
JDK_PATH ?= $(shell echo $$JAVA_HOME)

# 编译器和标志
CC = gcc
CFLAGS = -shared -fPIC -std=c99 -D_GNU_SOURCE
JNI_INCLUDE = -I$(JDK_PATH)/include -I$(JDK_PATH)/include/linux
#JNI_INCLUDE_LINUX = $(JDK_PATH)/include/linux


COMM_INC_BASE = ../common
GLIB_INC_BASE = -I./ -I../common/glib_include/glib-2.0/ -I../common/glib_include/glib-2.0/glib/ \
				-I../common/glib_include/glib-2.0/include/  -I../common/gmssl_include/

INCLUDE_PATH = $(JNI_INCLUDE) $(GLIB_INC_BASE)

# 目标文件和库文件
TARGET = libzcopy
LIBRARY = ../bin/libzcopy.so  # 修改为将生成文件放到 ../bin 目录

# 默认目标:编译共享库
$(LIBRARY): com_hess_jni_zcopy_HessZcopy.c ../common/log.c hess_jni_zcopy.c ../common/tools.c ../common/cjson/cJSON.c
	$(shell mkdir -p ../bin)  # 确保 ../bin 目录存在
	$(CC) $(CFLAGS) $(INCLUDE_PATH) -o $(LIBRARY) $^

# 清理生成的文件
clean:
	rm -f $(LIBRARY)

.PHONY: clean

Windows配置

  • 预处理器JNI_EXPORTS
  • 附加包含目录$(JAVA_HOME)\include
    • $(JAVA_HOME)\include\win32
  • 附加库目录
    • $(JAVA_HOME)\lib
  • 输入jvm.lib

项目代码,只记录接口部分

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

#ifndef _Included_com_hess_jni_zcopy_HessZcopy
#define _Included_com_hess_jni_zcopy_HessZcopy
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_hess_jni_zcopy_HessZcopy
 * Method:    status
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_hess_jni_zcopy_HessZcopy_status
  (JNIEnv *, jobject);

/*
 * Class:     com_hess_jni_zcopy_HessZcopy
 * Method:    config
 * Signature: (Ljava/lang/String;)Z
 */
JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_config
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_hess_jni_zcopy_HessZcopy
 * Method:    configWithFile
 * Signature: (Ljava/lang/String;)Z
 */
JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_configWithFile
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_hess_jni_zcopy_HessZcopy
 * Method:    start
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_start
  (JNIEnv *, jobject,
   jint sync_type, jstring source, 
   jstring dest, jstring confpath);

/*
 * Class:     com_hess_jni_zcopy_HessZcopy
 * Method:    stop
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_stop
  (JNIEnv *, jobject);

/*
 * Class:     com_hess_jni_zcopy_HessZcopy
 * Method:    diff file start
 * Signature: ()Z
 * param:     diff_rule use bitmap,"ct" 1, "ch" 2, "cs" 4, "ca" 8, "co" 16
 */
JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_diffstart
(JNIEnv *, jobject, jint diff_rule, jint max_num, jstring source, jstring dest);

/*
 * Class:     com_hess_jni_zcopy_HessZcopy
 * Method:    diff file stop
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_diffstop
(JNIEnv *, jobject);

/*
 * Class:     com_hess_jni_zcopy_HessZcopy
 * Method:    init
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_init
  (JNIEnv *, jobject);

  /*
 * Class:     com_hess_jni_zcopy_HessZcopy
 * Method:    uninit
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_uninit
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
#include "com_hess_jni_zcopy_HessZcopy.h"
#include "../common/log.h"
#include "../common/ztype.h"
#include "../common/tools_third.h"
#include "../common/tools.h"
#include "hess_jni_zcopy.h"
#include <string.h>
#include <stdlib.h>

char g_ctl_path[ZMAX_PATH] = {0};
#ifdef _MSC_VER
bool g_is_xp = false;
#endif
bool g_kill_needed = false;

const char* jstringToChar(JNIEnv *env, jstring jstr)
{
    if (jstr == NULL)
        return NULL;

    return (*env)->GetStringUTFChars(env, jstr, NULL);
}

// 辅助函数:抛出Java异常
static void throwJavaException(JNIEnv *env, const char *message)
{
    jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception");
    if (exceptionClass != NULL) {
        (*env)->ThrowNew(env, exceptionClass, message);
    }
    (*env)->DeleteLocalRef(env, exceptionClass);
}

JNIEXPORT jstring JNICALL Java_com_hess_jni_zcopy_HessZcopy_status(JNIEnv *env, jobject obj)
{
    // TODO: 实现获取实际状态的逻辑
    char *task_status_res = malloc(BUFFER_SIZE);

    log_info(__FILE__, __LINE__, "get_task_status start");
    int res = get_task_status(task_status_res, g_ctl_path);
    log_info(__FILE__, __LINE__, "get_task_status end res:%d task_status_res:%s", res, task_status_res);
    jstring status_res = (*env)->NewStringUTF(env, task_status_res);
    
    free(task_status_res);

    return status_res;
}

JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_config(JNIEnv *env, jobject obj, jstring jsonConfig)
{
    if (jsonConfig == NULL)
    {
        throwJavaException(env, "Config JSON string cannot be null");
        return JNI_FALSE;
    }
    
    const char *json_conf = (*env)->GetStringUTFChars(env, jsonConfig, NULL);
    if (json_conf == NULL)
    {
        throwJavaException(env, "Failed to get config string");
        return JNI_FALSE;
    }
    char *hotupdate_res = malloc(BUFFER_SIZE);

    log_info(__FILE__, __LINE__, "hotupdate_res start");
    int res = zcopy_hotupdate(hotupdate_res, g_ctl_path, json_conf);
    log_info(__FILE__, __LINE__, "hotupdate_res end  res:%d , string:%s", res, hotupdate_res);

    free(hotupdate_res);
    (*env)->ReleaseStringUTFChars(env, jsonConfig, json_conf);

    return res == E_CTL_CMD_RES_SUCCESS;
}

JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_configWithFile(JNIEnv *env, jobject obj, jstring configFilePath)
{
    if (configFilePath == NULL)
    {
        throwJavaException(env, "Config file path cannot be null");
        return JNI_FALSE;
    }
    
    const char *filePath = (*env)->GetStringUTFChars(env, configFilePath, NULL);
    if (filePath == NULL)
    {
        throwJavaException(env, "Failed to get file path string");
        return JNI_FALSE;
    }
    printf("Java_com_hess_jni_zcopy_HessZcopy_configWithFile!\n");
    // TODO: 实现文件配置处理逻辑
    jboolean success = JNI_TRUE;
    
    (*env)->ReleaseStringUTFChars(env, configFilePath, filePath);
    return success;
}

JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_start(JNIEnv *env, jobject obj,
                                                                    jint sync_type, jstring source, 
                                                                    jstring dest, jstring confpath)
{
    // TODO: 实现启动逻辑
    log_info(__FILE__, __LINE__, "zcopy_task_start sync_type %d", sync_type);
    if (sync_type > E_COPY_TYPE_END || sync_type < E_COPY_TYPE_REPRINT)
    {
        throwJavaException(env, "cmd error");
        return JNI_FALSE;
    }

    char *task_status_res = malloc(BUFFER_SIZE);
    const char *sourcec = jstringToChar(env, source);
    const char *destc = jstringToChar(env, dest);
    const char *confpathc = jstringToChar(env, confpath);


    log_info(__FILE__, __LINE__, "zcopy_task_start start");
    int res = zcopy_task_start(task_status_res, g_ctl_path, sync_type, sourcec, destc, confpathc);
    log_info(__FILE__, __LINE__, "zcopy_task_start end  res:%d , string:%s", res, task_status_res);
    
    free(task_status_res);
    (*env)->ReleaseStringUTFChars(env, source, sourcec);
    (*env)->ReleaseStringUTFChars(env, dest, destc);
    (*env)->ReleaseStringUTFChars(env, confpath, confpathc);

    return res == E_CTL_CMD_RES_SUCCESS;
}

JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_stop(JNIEnv *env, jobject obj)
{
    // TODO: 实现停止逻辑
    char *task_stop_res = malloc(BUFFER_SIZE);

    log_info(__FILE__, __LINE__, "zcopy_task_stop start");
    int res = zcopy_task_stop(task_stop_res, g_ctl_path);
    log_info(__FILE__, __LINE__, "zcopy_task_stop end  res:%d , string:%s", res, task_stop_res);
    free(task_stop_res);

    return res == E_CTL_CMD_RES_SUCCESS;
}

JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_diffstart(JNIEnv *env, jobject obj, jint diff_rule,
                                                                        jint max_num, jstring source, jstring dest)
{
    return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_diffstop(JNIEnv *env, jobject obj)
{
    return JNI_FALSE;
}

JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_init(JNIEnv *env, jobject obj)
{
#ifdef _MSC_VER
    g_is_xp = is_xp();
#endif
    jboolean success = JNI_TRUE;
    char log_path[ZMAX_PATH] = {0};

    get_process_path(g_ctl_path, ZMAX_PATH);
    sprintf_s(log_path, ZMAX_PATH, "%s%s", g_ctl_path, LOG_PATH);
    log_init(log_path, 0);
    strcat(g_ctl_path, CTL_PATH);
    
    return success;
}

JNIEXPORT jboolean JNICALL Java_com_hess_jni_zcopy_HessZcopy_uninit(JNIEnv *env, jobject obj)
{
    jboolean success = JNI_TRUE;
    return success;
}

windows使用ms visual stdio

相关文章:

  • springboot和springcloud的区别
  • 【Linux】Linux下的gcc/g++编译器与动静态库
  • #3 物联网 的标准
  • 巴法云平台-TCP设备云-微信小程序实时接收显示数据-原理
  • 生态环境影响评价技术体系构建与图件智能化实现‌‌—以内蒙古风电场建设项目为例
  • MySQL ROUND(number, decimals)
  • 访问不到服务器上启动的llamafactory-cli webui
  • 使用命令打开电脑的[服务]窗口
  • 微任务(Microtasks)与宏任务(Macrotasks)详解
  • 几何建模基础-拓扑命名实现及优化
  • 关于IDEA中使用ctrl跳转源码出现???的解决方案
  • OpenCV图像增强实战教程:从理论到代码实现
  • 约翰·麦卡锡:我的人工智能之梦
  • Linux中的线程
  • 小刚说C语言刷题——每日一题东方博宜1000熟悉OJ环境
  • VS 基于git工程编译版本自动添加版本号
  • 【网络安全】通过 JS 寻找接口实现权限突破
  • 【秣厉科技】LabVIEW工具包——OpenCV 教程(19):拾遗 - imgproc 基础操作(上)
  • 软件测试过程模型:v模型、w模型、x模型、H模型
  • 软件项目经理PM实战操作手册【附全文阅读】
  • 2025年度沪惠保参保今开启:保费不变,国内特药种类扩增
  • 元宇宙之问|“AI+AR”融合或重新定义元宇宙发展路径
  • 浙江一季度GDP为22300亿元,同比增长6.0%
  • 群内“分享”侵权书籍电子版,培训公司被判赔偿出版社2万元
  • 沙龙 | 新书分享:中国电商崛起的制度密码
  • 境外机构来华发行熊猫债累计超9500亿元