JNI入门学习笔记(测试环境:ubuntu gcc 4.4.5)

5个RADIUS开源框架横向对比:从FreeRADIUS到Netty-Radius的选型指南 本文深入对比了5个主流RADIUS开源框架,包括FreeRADIUS、TinyRadius、JRadius、Radius4J和Netty-Radius,从协议支持、性能表现、集成复杂度等维度进行全面分析。针对不同场景提供选型建议,帮助开发者选择最适合的网络认证解决方案,提升系统稳定性和开发效率。 阅读详情

参考文章:

http://blog.youkuaiyun.com/yuleslie/article/details/7056577

java native specification 官方文档。

深入理解android:卷1


我这里尝试写一个在ubuntu上直接运行的java调用jni程序,通过这个慢慢入门,然后提高吧。

1. 编辑一个java文件HelloJNI.java(名字随意),这个java文件会去调用jni的方法。

class HelloWorld
{
	private native void print();
	public static void main(String[] args)
	{
		new HelloWorld().print();
	}
	static
	{
		System.loadLibrary("MyJNI");
	}
}

不需要任何头文件包含。代码中看到有个main函数,另外main函数会调用native的print方法。

System.loadLibrary("MyJNI")是要我们要加载的JNI库,实际加载过程中会找这个拓展后的文件名,Linux下为libMyJNI.so,windows下为MyJNI.dll

接下来我们需要去建立我们的MyJNI库,并要保证我们调用native的print函数时能正常调用到JNI库中对应的XXX_print函数,所谓“注册JNI函数”。

2. 编写注册JNI函数

为保证我们JNI库中的函数与java中调用的print对应,我们需要完成JNI函数的注册,相当与映射的意思吧。

这里我们先测试使用简单的静态注册方法,为省去要按JNI规范手动编写代码的困难,我们使用javah来生成头文件。

先将上面的HelloJNI.java用javac编译成 .class文件

tongjiang@tongjiang-laptop:/home/workdir/source/test$ javac HelloJNI.java

此时目录下会根据你HelloJNI.java中定义的HelloWorld类生成一个文件:HelloWorld.class

我们此时使用javah来生成.h文件

tongjiang@tongjiang-laptop:/home/workdir/source/test$ javah HelloWorld

这样会生成HelloWorld.h 头文件,内容如下

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

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    print
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_print
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

我们如果自己手动coding的话就要按JNI规范来写,JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject)

我们在jni库中要编写的print函数的原型就是这样了,print被扩展为Java_HelloWorld_print,

静态注册时虚拟机会按这种扩展方法来找jni函数。

另外还有搞怪的,如果我们java文件中print函数是写成有下划线的,假如是print_me,

扩展时需要写成JNIEXPORT void JNICALL Java_HelloWorld_print_lme(JNIEnv *env, jobject)

注意me前面的那个l,另外如果print函数有传参进来时,JNI对应的函数原型的参数需要按JNI的数据类型进行转换,这个是后话。

3. 我们按.h文件的函数原型来写native的c++代码:hello.cpp

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

JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
	printf("Hello, i am Native\n");

	return ;
}

单纯打印一句话: Hello, i am Native

我们来编译一下这个cpp文件

tongjiang@tongjiang-laptop:/home/workdir/source/test$ g++ -shared -I '/home/tongjiang/Program/jdk1.6.0_25/include' -I'/home/tongjiang/Program/jdk1.6.0_25/include/linux' '/home/workdir/source/test/hello.cpp' -o libMyJNI.so

-shared会把cpp编译成动态库

-o 输出的目标文件,我们这里是动态库libMyJNI.so

-I 是include头文件的目录 jni.h在jdk1.6.0_25/include'中,而jni.h又包含的头文件在jdk1.6.0_25/include/linux中.

4. 我们可以去尝试java调用jni了

我们运行java HelloWorld

tongjiang@tongjiang-laptop:/home/workdir/source/test$ java HelloWorld
Exception in thread "main" java.lang.UnsatisfiedLinkError: no MyJNI in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)
	at java.lang.Runtime.loadLibrary0(Runtime.java:823)
	at java.lang.System.loadLibrary(System.java:1028)
	at HelloWorld.<clinit>(HelloJNI.java:10)
Could not find the main class: HelloWorld.  Program will exit.

提示找不到这个库no MyJNI in java.library.path,因为System.loadLibrary会到系统库中找对应的so,但我们的so没有放到系统的lib目录中。

我们这里可以配置export LD_LIBRARY_PATH=/home/workdir/source/test

这样的话会链接LD_LIBRARY_PATH这个目录下的对应so

再次运行java HelloWorld

tongjiang@tongjiang-laptop:/home/workdir/source/test$ java HelloWorld

Hello, i am Native

也可以不export LD_LIBRARY_PATH

执行下面的命令也ok

tongjiang@tongjiang-laptop:/home/workdir/source/test$ java -Djava.library.path=./ HelloWorld 
Hello, i am Native


好,现在我们基本通路已经打通了,java能通过jni调用native层的的函数,我们再尝试函数中传递参数和native调用java层的方法。



DNS超时机制深度解析:9527背后的5秒设计原理与工程实践 DNS超时是网络通信中影响应用可用性的基础机制,其核心在于客户端解析器对查询响应的等待策略。该机制源于RFC 1035对重试与超时的开放性要求,并在glibc、BIND、CoreDNS等主流实现中收敛为默认5秒单次查询超时——这一数值经十六进制调试标识演化为工程界广泛认知的‘9527’代号。它并非协议强制标准,而是操作系统资源约束、广域网传输抖动容忍度与用户感知延迟三者权衡的结果。在Kubernetes服务发现、移动端弱网解析、云原生递归解析器健康探测等典型场景中,该超时直接决定P95解析耗时、雪崩风险与故 阅读详情

相关推荐

AI工程化语言选型:Python、Rust、Java、Go在真实场景中的不可替代性

编程语言是AI工程落地的核心载体,而非算法研究的附属工具。理解语言的本质需回归其设计目标:Python以开发效率和生态丰富性支撑快速实验;Rust凭借内存安全与零成本抽象成为高并发推理与基础设施的首选;Java依托JVM成熟度与企业级集成能力,稳坐风控、金融等关键系统的‘压舱石’;Go则以轻量协程和单二进制部署专治Python服务的性能瓶颈。这些语言的价值不在语法优劣,而在于它们如何匹配数据预处理、模型训练、边缘推理、系统集成等不同阶段的刚性约束。本文基于23个工业级AI项目实践,解析六种主流语言在AI全链

weixin_33858485的博客 735

JNI使用--ubuntu篇

关于Windows JNI使用,我在上一篇博客中已经详细说明 https://blog.csdn.net/qq_28398393/article/details/90580729 本篇博客主要介绍 在 ubuntu下,如何使用 JNI 一,环境: ubuntu16.04,gcc 二,使用方法: 1.创建一个java文件(JNITest.java) 采用load函数装载动态链接库,要使...

qq_28398393的博客 576

从x86到ARM架构迁移实战:能效比、容器化与性能调优指南

在云计算与数据中心领域,处理器架构的选择直接影响着系统的性能、成本与扩展性。复杂指令集(CISC)与精简指令集(RISC)是两种主流的处理器设计哲学,前者以x86架构为代表,长期主导服务器市场;后者以ARM架构为核心,凭借其高能效比和核心密度优势,正快速向云端和边缘计算渗透。从技术原理看,ARM架构采用精简指令集,核心设计更高效,允许在相同功耗下集成更多计算单元,这为大规模分布式部署和容器化环境带来了显著的性价比提升。其技术价值体现在通过软硬件垂直整合,为特定负载(如Web服务、数据处理、微服务)提供定制化

weixin_30660027的博客 337

Ubuntu下JNI的简单使用

<br />1、创建一个java文件(HelloWorld.java)。<br />     class HelloWorld { static { System.loadLibrary("HelloWorld"); } private native void prin

JasonZhang 9360

ARM架构存储性能测试实战:Vdbench部署、调优与结果分析

存储性能测试是评估存储系统处理能力、延迟和稳定性的关键环节,其核心原理是通过模拟特定I/O负载来量化存储设备的吞吐量、IOPS等关键指标。在云计算、边缘计算和物联网等场景中,准确的性能基线数据对于系统选型、容量规划和故障排查具有重要价值。随着ARM架构在服务器和终端设备中的广泛应用,如搭载飞腾、鲲鹏处理器的服务器,在其上进行存储性能测试的需求日益增长。Vdbench作为一款功能全面的开源基准测试工具,能够模拟复杂的读写模式,是进行此类评估的常用选择。本文将聚焦于在ARM Linux系统上,从环境准备、编译部

weixin_34320159的博客 380

逆向工程实战:从二进制分析到0Day漏洞挖掘的完整路径

在软件安全领域,逆向工程是通过分析二进制代码理解程序内部逻辑的核心技术。其基本原理是将编译后的机器码转换为可读的汇编或高级语言表示,从而揭示程序的实际行为。这项技术的核心价值在于能够发现开发者未预料的安全缺陷,特别是那些用非内存安全语言编写的复杂软件组件。在实际应用场景中,逆向工程常与模糊测试技术结合,用于自动化挖掘缓冲区溢出、释放后重用等内存破坏漏洞。通过静态分析工具识别危险函数调用模式,再结合覆盖引导的Fuzzing进行动态验证,研究人员能够系统性地发现0Day漏洞。本文以实战为导向,详细解析了从目标筛

weixin_33700350的博客 477

linux/ubuntu下使用jni的demo

1环境:      1)系统:Linux ubuntu 3.2.0-32-generic-pae #51-Ubuntu SMP Wed Sep 26 21:54:23 UTC 2012 i686 i686 i386 GNU/Linux      2)gcc编译器:gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3      3)jdk:jdk1.6.0_34

技术的学习与积累是个技术活 1563

Java+多GPU部署LLaMA2:llama.cpp JNI与显存规划全解析

在Java技术栈主导的企业环境中,将大语言模型推理能力无缝集成到现有微服务体系,是许多开发团队面临的现实挑战。大模型推理通常依赖Python生态,但Java凭借其成熟的内存管理、高并发架构与运维体系,同样可以在多GPU环境下实现高效部署。其核心原理在于通过JNI桥接C++推理引擎llama.cpp,以层间切分方式将Transformer层分布到多张显卡,配合GGUF量化格式与KV Cache规划,在降低单卡显存压力的同时提升吞吐能力。这种方案广泛应用于智能客服、代码生成、知识库问答等业务场景,尤其适合已有J

weixin_32430941的博客 347

Ubuntu 10.10 中文化GCC4.5和Code::Blocks中文化编程

landboy@ubuntu:~$ sudo apt-get install gcc [输入TAB键两下会出来下面的列表]gcc                             gcc-4.4-multilibgcc-4.1                         gcc-4.4-sourcegcc-4.1-base                    gcc-4.5gcc-4.1-doc                     gcc-4.5-arm-linux-gnueabigcc-4

hongwenjun的专栏 3531

AI辅助专利撰写实战:30分钟高效产出发明专利初稿

在技术创新的浪潮中,专利撰写常常是开发者将创意转化为知识产权保护壁垒的关键一步,但这个过程往往耗时费力,需要兼顾技术深度与法律文书规范。近期,借助AI辅助工具来提升专利撰写效率已成为一个热门探索方向。本文将围绕如何利用AI工具,在30分钟内高效完成一篇具备授权潜力的发明专利初稿,进行一场从0到1的实战演练。无论你是独立开发者、初创团队的技术负责人,还是希望保护自己研究成果的学生,这套方法都能帮助你快速梳理技术方案,形成结构严谨、逻辑清晰的专利申请文档。 1. 背景与核心概念:AI辅助专利撰写的价值与边界 在

weixin_34253126的博客 494

从d、q轴电流到电机性能:FOC控制中角度偏移的实战影响与调试策略

本文深入探讨了永磁同步电机FOC控制中d、q轴电流与角度偏移对电机性能的影响及调试策略。通过分析角度偏移导致的效率下降、电流异常等问题,提供了实用的四步调试法和参数优化技巧,帮助工程师有效提升电机控制精度和效率。

weixin_29264201的博客 294

ubuntu下jni的简单使用,不使用ndk工具

jdk的安装什么的就省略了 1.编写HelloJNI.java 2.生成.class文件 javac HelloJNI.java 3.生成HelloJNI.h javah HelloJNI或者javah -jni HelloJNI 4.编写hellojni.c 5.复制头文件 sudo cp jdk目录/include/jni.h /usr/include/ sudo

u011068616的专栏 597

A股量化实战:用Python回测动量因子策略(附聚宽完整代码)

本文详细介绍了如何在A股市场使用Python和聚宽平台,实战回测一个动量因子量化交易策略。从环境搭建、数据获取到完整的策略代码实现与回测分析,手把手教你验证“强者恒强”的投资逻辑,并提供参数优化与实战避坑指南,助力量化新手迈出第一步。

weixin_29264201的博客 969

嵌入式开发学习笔记 ( java - c/c++ :从入门到入门 )

发现放到优快云之后排版全乱套了。。已经在我自己的站点重新排版: Github · 目录 导 航 1.引言 1.1.编写目的 1.2.阅读范围 1.3.声明 1.4.缩写词/名词解释 1.5.参考资料 2.嵌入式开发学习笔记 2.1.开发环境/测试环境 ...

ζёСяêτ - 小優YoU 1万+

IMU标定中的Allen方差

Allen方差 Allen方差是IMU标定任务中的常用工具。IMU标定可以分为确定性误差和随机误差,确定性误差包括:scale、bias、misalignment。随机误差则主要是高斯白噪声和bias随机游走。Allen方差主要用于标定随机误差。 Allen方差获取 Allen方差的计算方法如下: 保持IMU静止, 采集N个数据点。 将N个点定长分组,常用的交叠式Allen方差如下(n=3): 对于每个子集,计算均值后,计算相邻两组的方差,得到的时间-方差曲线即为Allen方差。 Alle

realjc的博客 5734

由JavaScript版迷宫游戏引出Java版迷宫地图生成器

Java案例:迷宫地图生成器 一、引入问题 本期18软件1班网页脚本实训项目是完成一个JavaScript版迷宫游戏。 迷宫地图是如何生成的呢?很简单,将一个正方形区域等分为若干行与若干列,比如25行25列,这样就有625个单元格,用一个二维数组map[25][25]就可以保存625个单元格信息,map[i][j] = 1表示该单元格要绘制砖,而map[i][j] = 0表示该单元格不绘制砖。 ...

howard2005的专栏 1472

jni练习(一)

在浏览android源码 或者 开发java程序,有时我们会需要用到jni。 一直以来都只是知道一个大体的概念,没有手动尝试,今天心血来潮手动测试了一下。 测试环境: ubuntu 12.04 1. jnitest.c测试代码: public class jnitest{ static{ System.loadLibrary("jni

hhh3214的专栏 445

SerDes系列之如何选择AC耦合电容

交流耦合电容用于隔离PCB互连时的直流分量(Common-mode voltage),同时传递交流分量(Voltage swing),其作用类似于一个高通滤波器,但是,如果电容容值选取不当,使用过程中会产生信号质量问题,典型的应用场景:当包含相同的长串1或0的NRZ数据应用于该高通滤波器时,会发生低频电压跌落,导致低频模式相关抖动(PDJ)。

一只豌豆象的博客 2351

Zabbix 社区模板实战:通过 SNMP 发现并执行 MikroTik 脚本(Mikrotik Script Execution via SNMP)

本文深入解析 Zabbix 社区模板仓库中的 **Mikrotik Script Execution** 模板(作者 Antonio Forster),该模板利用 SNMP 低层发现(LLD)机制自动发现 RouterOS 路由器上所有以 `Get` 开头的脚本,并将每个脚本的执行结果作为独立的监控项写入 Zabbix,从而可以直接绘图、创建触发器与告警。读完本文,你将掌握该模板的 OID 结构、

gitblog_00772的博客 962

20、认知负荷理论在教育技术中的应用

本文深入探讨了认知负荷理论(Cognitive Load Theory, CLT)在教育技术中的应用,重点分析了如何通过优化教学设计减少学习者的认知负荷,提高学习效率。文章介绍了认知负荷的三种类型:内在认知负荷、外在认知负荷和germane认知负荷,并结合多媒体学习原则(如模态效应、空间连续性原则、时间连续性原则等)提出了减少外在认知负荷的具体策略。此外,文章通过实证研究和教学案例,展示了认知负荷理论在不同学科和个性化教学中的广泛应用和有效性。最终,文章总结了应用认知负荷理论进行教学设计的具体流程,强调其在

solidity8miner的博客 923

Qt c++ llama.cpp 运行 LLaMA-3-8B 中文对话机器人(多模态输入)

助手:

寒寒豆豆软件公司的博客 219

从源码编译 QFS:Quantcast File System 在 Linux 与 macOS 上的完整构建指南

QFS(Quantcast File System)是 Quantcast 开源的高性能、高容错分布式文件系统,专为 MapReduce 等顺序读写大文件的场景设计。如果你不想直接使用二进制发行包,而是希望从源码编译 QFS,掌握完整的构建流程,那么本文就是为你准备的:从依赖安装、源码获取,到编译调试与验证部署,一份在 Linux 与 macOS 上都能顺畅照做的完整指南。 [![QFS 分布式

gitblog_00928的博客 835

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

ff/ffi-overhead震撼结果:LuaJIT竟比C语言快26%?深度解析

在软件开发中,跨语言调用的性能开销一直是开发者关注的焦点。**ff/ffi-overhead**项目通过对比多种编程语言调用C语言函数的性能表现,揭示了不同语言在FFI(Foreign Function Interface)实现上的巨大差异。本文将深入分析测试结果,解释为何LuaJIT能超越C语言本身,并为开发者选择合适的语言提供参考。 ## 测试项目概述:20亿次调用的极限挑战 **ff/f

gitblog_01188的博客 278

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Qwen3.6-Plus编程能力实测:真实工程场景下的代码生成与落地验证

大模型编程能力已从算法题解迈入真实工程实践阶段。理解代码生成的本质,需回归其底层原理——基于海量开源代码训练形成的模式识别与上下文推理能力,并通过编译器反馈强化学习(Compiler-Feedback RL)持续优化输出质量。这种能力带来显著技术价值:提升开发效率、降低文档查阅成本、辅助遗留系统维护与安全缺陷定位。典型应用场景包括CI/CD流程嵌入、跨语言胶水代码编写、Swagger到云原生配置转换、生产级错误诊断及多语言环境适配。本文聚焦Qwen3.6-Plus在真实需求驱动下的编程表现,覆盖环境感知、上

优快云头条 402

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Android上的Limbo虚拟机终极指南:如何在移动设备上运行Windows和Linux系统

Limbo是一款基于QEMU的Android平台虚拟机软件,它能够将你的Android设备转变为一台功能完整的虚拟计算机。这款强大的Android虚拟机支持x86、ARM、PowerPC和SPARC等多种架构模拟,让你能够在手机上运行Windows、Linux等操作系统,为移动设备带来了前所未有的虚拟化能力。 ## 📱 项目概述与核心价值 ### 什么是Limbo虚拟机? Limbo是一个

gitblog_00920的博客 1059

软件交付中的高频技术陷阱:从现象描述到自动化解法

在分布式系统与云原生交付实践中,‘技术陷阱’并非偶然故障,而是由认知断层、环境差异和流程盲区共同导致的可复现问题模式。其本质是现象描述失焦、实例不可验证、解法不可沉淀——例如时间同步漂移引发gRPC超时、数据库连接池泄漏导致OOM、Alpine镜像因musl/glibc兼容性触发undefined symbol错误。这些问题虽表现各异,但共性在于:缺乏标准化描述框架、缺少最小可复现实例、解法无法嵌入CI/CD流水线。真正有效的应对不是经验式重启或临时补丁,而是将根因转化为可编码、可审计、可度量的工程动作,如

weixin_34129696的博客 413
上一篇: Andriod 杂记
下一篇: Linux下的管道编程技术-dup函数和dup2函数
evilcode
博客等级 码龄20年 307粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值