JNI基础知识(三)C++的特别之处

JNI方法调用C++类库<一> 布局: C++ ------------>lib,文件dms_lib.cpp C++ ------------>JNI C++,文件dms_jni.cpp JAVA ------------>JNI JAVA,文件dms.java 通过以下命令,可以生成java的jni头文件:javac dms.java && javah dms /**  * file: dms.java  * 阅读详情

我们在写JNI开发时,会经常遇到C和C++混编的情况,那我们如何做好区分呢?那只能我们多注意其实现。

首先来看下C++跟C有哪些不同吧:

1、输出

我们是到在C语言中我们输出一般都是用到printf这个函数,但在C++中则不一样,首先其输出库为“iostream”写法如下:

std::cout << "this is c plus plus" << std::endl;

我们可能对“::”这个很不习惯,这个叫做:运算符重载,当然我们也可简化我们的写法,用的C++中的命名空间

//标准命名空间(包含很多标准的定义)
//standard
using namespace std;
//命名空间类似于Java中包(归类)

cout << "this is c plus plus" << endl;

这样写可能就不叫舒服的多啦。当然我们也可以自定义命名空间:

//自定义命名空间
namespace CUSTOM_A{
	int a = 9;
	struct Teacher{
		char name[20];
		int age;
	};
	struct Student{
		char name[20];
		int age;
	};
	
}

namespace CUSTOM_B{
	int a = 12;
	//命名空间嵌套
	namespace CUSTOM_C{
		int c = 90;		
	}
}

void main(){
	cout << CUSTOM_A::a << endl;
	cout << CUSTOM_B::a << endl;
	cout << CUSTOM_B::CUSTOM_C::c << endl;

	//使用命名空间中的结构体
	using CUSTOM_A::Student;
	Student t;
	t.age = 90;

	system("pause");
}

2、类对象

#define PI 3.14
//圆
class MyCircle{
//属性(共用权限访问修饰符)
private:
	double r;
	double s;
public:
	void setR(double r){
		this->r = r;
	}
	//获取面积
	double getS(){
		return PI * r * r;
	}
};

void main(){
	MyCircle c1;
	c1.setR(4);

	cout << "圆的面积:" << c1.getS() << endl;

	system("pause");
}

我们可以发现跟Java还是很像的,但是还有细微的区别,我们使用的时候要注意,比如声明的时候不用new关键字,new之后再讲。

3、结构体

结构体跟C语言的写法也不太一样,我们来看下:

struct MyTeacher{
public:
	char name[20];
	int age;
public:
	void say(){
		cout << this->age << "岁" << endl;
	}
};
void main(){
	MyTeacher t1;
	t1.age = 10;
	t1.say();
	system("pause");
}

我们可以发现其包含了属性在内,而且使用的时候可以不用struct声明。

4、布尔类型

不同于C语言,C++中加入布尔类型,我们来看一下:

void main(){
	//bool isSingle = true;
	bool isSingle = 17;
	//false -17

	if (isSingle){
		cout << "单身" << endl;
		cout << sizeof(bool) << endl;
	}
	else{
		cout << "有对象" << endl;
	}

	int a = 10, b = 20;
	((a > b) ? a : b) = 30;
	cout << b << endl;

	system("pause");
}

我们在上面代码有一点需要注意,不同于我们平时的Java语法,在C++中三目运算可以作为左值,如上面的代码,其b的值输出为30,发生了改变,切记注意。

5、引用

做为C++中最代表性的概念,其对于C++的地位就同与指针对于C的重要。看下基本写法:

void main(){
	//变量名-门牌号(内存空间0x00001的别名,可不可以有多个名字?)
	int a = 10;
	//b就这个内存空间另外一个别名\
	//& C++中的引用
	int &b = a;	
	cout << b << endl;

	system("pause");
}

我们跟指针做一下对比,发现其写法还是比较简单的:

//指针值交换
void swap_1(int *a, int *b){
	int c = 0;
	c = *a;
	*a = *b;
	*b = c;
}

//引用值交换
void swap_2(int &a, int &b){
	int c = 0;
	c = a;
	a = b;
	b = c;
}

void main(){
	int x = 10;
	int y = 20;
	
	printf("%d,%d\n",x,y);
	//swap_1(&x, &y);
	//a成了x的别名
	swap_2(x,y);
	printf("%d,%d\n", x, y);

	system("pause");
}

我们再看一下作为参数传递对比:

struct Teacher{
	char* name;
	int age;
};

void myprint(Teacher &t){
	cout << t.name << "," << t.age << endl;
	t.age = 21;
}

void myprint2(Teacher *t){
	cout << t->name << "," << t->age << endl;	
	//(*t).name 
}

//引用的主要功能:作为函数的参数或返回值
void main(){
	Teacher t;
	t.name = "Jason";
	t.age = 20;
	myprint(t);

	myprint2(&t);

	system("pause");
}

 当然我们也可以作为指针的引用,这样其实现方式就更加丰富啦:

//指针的引用,代替二级指针
struct Teacher{
	char* name;
	int age;
};

void getTeacher(Teacher **p){
	Teacher *tmp = (Teacher*)malloc(sizeof(Teacher));
	tmp->age = 20;
	*p = tmp;
}

//指针的引用,代替二级指针
//Teacher* &p = (Teacher * *p)
void getTeacher(Teacher* &p){
	p = (Teacher*)malloc(sizeof(Teacher));
	p->age = 20;
}

void main(){
	Teacher *t = NULL;

	getTeacher(&t);

	system("pause");
}

 还有一个经常被面试问到,也经常弄混的一个感念,我们要区别一下:指针常量和常量指针。

我们来具体看下两种写法有什么不一样:

void main(){
	//指针常量,指针的常量,不改变地址的指针,但是可以修改它指向的内容
	int a = 2, b = 3;
	int *const p1 = &a;
	//p1 = &b;  //NO
	*p1 = 4;

	//常量指针,指向常量的指针,内容不能修改
	const int *p2 = &a;
	p2 = &b;
	//*p2 = 9;  //NO
}

补充:const 也有许多可分析的东西,简单分析一下。之后单独抽出来分析

//常引用类似于java中final
void myprintf(const int &a){
	cout << a << endl;	
}

void main(){	
	//const int a;
	//引用必须要有值,不能为空
	//int &a = NULL;

	//常引用
	int a = 10, b = 9;
	const int &c = a;

	//字面量
	const int &d = 70;

	//c = b;
	myprintf(c);
	
	system("pause");
}

再看看一下引用的大小:

struct Teacher{
	char name[20];
	int age;
};

void main(){
	Teacher t;

	Teacher &t1 = t;
	Teacher *p = &t;

	cout << sizeof(t1) << endl;//24
//	cout << sizeof(p) << endl;//4
//	cout << sizeof(Teacher) << endl;//24
	system("pause");
}

总结一下:

1.单纯给变量取别名没有任何意义,作为函数参数传递,能保证参数传递过程中不产生副本

2.引用可以直接操作变量,指针要通过取值(*p),间接操作变量,指针的可读性差

6、函数参数

a、函数默认参数

void myprint(int x, int y = 9, int z = 8){
	cout << x << endl;
}
//重载
void myprint(int x,bool ret){
	cout << x << endl;
}

void main(){
	myprint(20);

	system("pause");
}

分析一下:1、不同于java可以传入默认值的参数,注意的是前面一个是传默认值的,后面的也必须传默认值。

                  2、重载的函数不能有可二性,就是其可传参数不能一样。

b、可变参数

void func(int i,...)
{
	//可变参数指针
	va_list args_p;
	//开始读取可变参数,i是最后一个固定参数
	va_start(args_p,i);
	int a = va_arg(args_p,int);
	char b = va_arg(args_p, char);
	int c = va_arg(args_p, int);
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
	//结束
	va_end(args_p);
}


void main(){
	func(9,20,'b',30);

	system("pause");
}


//循环读取
void func(int i,...)
{
	//可变参数指针
	va_list args_p;
	//开始读取可变参数,i是最后一个固定参数
	va_start(args_p,i);
	int value;
	while (1){
		value = va_arg(args_p,int);
		if (value <= 0){
			break;
		}
		cout << value << endl;
	}

	//结束
	va_end(args_p);
}

void main(){
	func(9, 20, 40, 30);

	system("pause");
}

注:读取可变参数要引入“stdarg.h”头文件。



 

Java通过JNA或JNI调用C++动态库 阅读详情

相关推荐

使用C++实现JNI接口需要注意的事项

Android NDK带的jni例子都是使用C定义JNI接口,但是在项目中,因为Native代码是用C++编写的,所以我就使用C++定义JNI接口。没有想到,问题来了,现将问题总结如下:1、JNIEnv *env参数的使用所有JNI接口的第一个参数是JNIEnv *env, 在C中,使用方法是(*env)->NewStringUTF(env, "Hello from JNI!");但在C++中,其调用方法是env->NewStringUTF("Hello from JNI!");为什么有这种区别呢,看看jn

K.I.S.S - Keep It Simple, Stupid 7839

JNI/NDK入门指南之C/C++结构体和Java对象转换方式一

     C/C++结构体和Java对象之间通过Jni相互转换方式一    在Jni的开发过程中,会经常遇到有将C/C++结构体和Java对象之间相互转换的一些需求。那么接下来,在本文的篇章中我讲会将具体讲解两种方式,并且这两种方式在实际工作中会经常使用到。下面正式开始我们的本篇介绍之旅,介绍其中的一种。 一.方法介绍    第一种方法使用的是ByteBuffer作为...

IT先森 4273

Java JNI 调用C#方法

 在编写Java应用程序当中,可以利用C或者CPP来编写DLL函数,然后再Java当中进行调用,从而实现对本地API的调用,这两天因为业务需要,要利用Java调用C#函数。于是研究了一下,发现可以通过Manage C++来实现对C#函数的调用。具体方法如下:首先还是编写Java,利用javah生成CPP头文件。然后跟普通JNI编写过程一样。然后在JNI的借口函数出调用Manage C++方法。

sweetwxh的专栏 9326

JNI调用c++函数,该函数的参数是结构体(——对象的传递)

第三方C++函数接口为 int api_get_logfile(Struct fileinfo tfile),参数是个结构体,且套了另一个结构体: struct fileinfo{  char *fullpath;  int filesize;  int filemode;  struct disnode *tnode; }; struct disnode{  int nu

haoruifly的专栏 6580

Aloudata Agent :基于 NoETL 明细语义层的分析决策智能体

这是包括我们在内的一些厂商探索的一个新方向,这种方式先由大模型将自然语言转化为对指标语义层的查询请求(MQL,Metrics Query Language),再由指标平台将指标和维度的查询与计算逻辑转化为准确的 SQL 查询语句。用户查询经大模型语义解析后,将其转换为指标、维度及筛选条件的组合表达,并生成面向指标平台的 MQL,Aloudata CAN 指标平台的语义引擎将 MQL 转换为准确和可执行的查询 SQL,语义引擎内置函数体系与 SQL 解析器,确保语义转换的 100% 准确性。

Aloudata的博客 1663

五子棋ai:极大极小搜索和α-β剪枝算法的思想和实现(qt和c++)(一)引言和界面设计

引言 alphaGo击败围棋冠军李世石的新闻让我对棋类博弈产生了浓厚的兴趣,无奈本人不会围棋,但算是一个五子棋业余爱好者,于是乎希望通过实现一个五子棋ai来了解相关算法和知识。 五子棋在英文中又称Gobang,five-in-row,还有两个称呼:gomoku和renju(连珠)。我来简要介绍一下区别。由于五子棋已经被机器严格证明了是一种**“不公平”的游戏,先手黑子是绝对占优的,并且先手有必胜*...

livingsu的博客 1万+

利用VC++6.0实现JNI的最简单的例子

如何使用JNI的一些基本方法和过程在网上多如牛毛,如果你对Jni不甚了解,不知道Jni是做什么的,如何建立一个基本的jni程序,或许可以参考下面下面这些文章:利用VC++6.0实现JNI的最简单的例子 JNI入门教程之HelloWorld篇 SUN JNI Tutorial这些资料的例子中,大多数只是输入一些简单的参数,获取没有参数。而在实际的使用过程中,往往需要对参数进行处理转换。才可以被C/C

realAsker的专栏 2456

ISO7816协议深度解析-简单易懂协议详解(一)-- 复位,字符帧,及ATR

1. 摘要 IC卡必须支持T=0或T=1的协议,但不是同时支持这两种协议,而终端则必须同时支持T=0和T=1的协议。 • T=0通讯协议是异步半双工字符传输协议; • T=1通讯协议是异步半双工块传输协议; 在ISO7816-3标准中,具体规定了这两种协议:T0和T1。 IC卡所用的协议在TD1中指定,如果在复位应答信息中没有TD1,则表示用T=0的协议进行通讯。在复位应答后,IC卡和终端之间即用IC卡指定的协议进行通讯。 2. 硬件接口 1)VCC:电源输入(A类:5V, B类:3V) 2)GND:地 3

代码打工人的博客 4万+

Android NDK重定向std::cout输出到log

Android NDK重定向std::cout输出到log

zaffix的专栏 4099

Laravel 结合 jwt-auth 实现无状态 API 认证(实战解析)

本文详细解析了如何在Laravel框架中结合jwt-auth实现无状态API认证,包括JWT的优势、环境搭建、Token签发与刷新、API路由保护等实战内容。通过具体代码示例和优化技巧,帮助开发者高效解决跨域认证问题,提升系统安全性。

weixin_29315569的博客 210

Latex小白也能搞定!5分钟教你用Overleaf打造个性化简历(附免费模板)

本文为LaTeX新手提供了一份快速上手指南,教你如何在5分钟内使用Overleaf在线平台和现成模板,轻松打造专业且个性化的简历。文章详细介绍了从选择模板、替换个人信息到进行颜色、图标等个性化调整的完整流程,让你无需深入学习LaTeX语法,即可高效制作出排版精美、脱颖而出的求职简历。

2a4s6d8f0g的博客 682

JNI编程

JNI介绍 Java 本机接口(Java Native Interface (JNI))是一个本机编程接口,它是 Java 软件开发工具箱(Java SoftwareDevelopment Kit (SDK))的一部分。 JNI允许 Java 代码使用以其它语言(譬如 C 和 C++)编写的代码和代码库。Invocation API(JNI 的一部分)可以用来将 Java 虚拟机(

scusyq的专栏 745

RK3588 实战级 YOLOv5 Android 全解析:NPU 量化 + 多线程 + 跟踪算法,源码一次买齐

本文将带你完成一个完整的AI视觉项目:在搭载RK3588芯片的Android开发板上运行实时目标检测与跟踪应用。实战目标:成功运行官方YOLOV5摄像头实时检测案例技术深度:深入理解RKNN开发框架和源码实现核心技能:掌握NPU推理、多线程并发、目标跟踪等关键技术。

FJN110的博客 156

安卓JNI基础知识

JNI 是java原生接口(Java Native Interface),它定义了 Android 从受管理代码(使用 Java 或 Kotlin 编程语言编写)编译的字节码与原生代码(使用 C/C++ 编写)进行交互的方法,也就是安卓通过JNI技术提供Java调用C/C++或者C/C++调用Java的能力。JNI 不依赖于供应商,支持从动态共享库加载代码,虽然有时较为繁琐,但效率较高。

Watom_663的博客 1259

在 SAP GUI 里开发与调用 Adobe PDF 表单:SFP 建模 + Driver Program 调用的全流程实战

本文介绍了在SAP系统中使用Adobe PDF表单的完整流程。重点阐述了SAP Interactive Forms相比传统表单工具的优势,特别是在处理复杂排版、条码和交互式字段时的适用性。文章详细说明了开发流程:从安装设计工具Adobe LiveCycle Designer开始,到在SFP事务码中创建Interface和Form的数据模型,再到编写驱动程序的ABAP代码实现PDF输出。特别强调了Interface作为数据契约的重要性,以及如何通过分层设计实现前后端分离开发。最后提供了标准调用链的示例代码,展

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 273

17track单号查询逆向分析

这就说明该网站很有可能存在其它检测点,而检测本地替换最大可能的就是检测了代码格式化或者代码长度。也一样,要么导致网站卡死,要么会导致网页加载异常,这里可能就难到不少人了,让我们一步一步解决。而这个站主要是检测了代码格式化,无限循环检测造成了网站卡死,经多次测试发现检测点共三处。方法中代码很长,但是经调试后发现,它其实只返回一个固定的值,这里直接写死即可。同样的,虽然看起来很长,但是跟过之后就会发现流程很简单,这里主要就是对。追加了一些值,是一条很长的语句,整理代码。,核心流程也很简单,稍微跟一下就出来了,

pyzzd的博客 1621

JNI基础知识总结

JNI(Java Native Interface)是Java提供的一种编程框架,用于实现Java代码与本地(Native)代码(如C、C++等)之间的交互。JNI允许Java应用程序调用本地代码,并且本地代码可以调用Java代码,实现更高性能的操作或访问底层资源。

金戈鐡馬 3669

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

JNI调用CPP程序

创建JNITest类,并包含一个未定义的native方法shit() cmd窗口中cd 到项目的src目录下(此处可能根据jdk等版本有差异?),并执行javah -jni practice.JNITest(类的全限定类名 ) : 执行成功后在项目的bin目录下会生成相应的JNI头文件: 该头文件中引入了一个JNI头文件,之后会说,同时该头文件定义了JNITest类中需要在cpp中被实现的native方法,注意需要在此处同时include一个jni_md.h的头文件,否则JNIEXPORT会报错,同样一

qq_33804124的博客 721

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Android JNI 中 cpp 线程中调用 java 方法

Linux 下 JNI 实现 Java 调用 c的例子 c/cpp 调用 Java 方法的重点: jclass 是由 jobject public 继承而来的子类,所以它当然是一个 jobject,需要创建一个 global reference 以便日后使用。 jmethodID/jfieldID 与 jobject 没有继承关系,它不是一个 jobject,只是个整数,所以不存在被...

qq_38907791的博客 975

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

JNI开发笔记(三)--JNI工程的框架分析

JNI工程的框架分析引1. JNI工程的组成部分2. 各个部分之间的关系 引 JNI开发笔记(一)–Android Studio安装与环境搭建 JNI开发笔记(二)–创建JNI基础工程并运行 1. JNI工程的组成部分 Android Studio 4.0以后的版本可以直接建立JNI的基础工程并且可以直接运行,这个在JNI开发笔记(二)中已经实现,这篇文章就重点讲述一下JNI工程的组成部分以及各个部分之间的关系。 如下图所示,Android Studio自带的JNI模板工程中最重要的三个文件是红框中的部分:

魔法师の屋子★↓☆ 3833

JNI 基础知识

JNI 基础知识 什么是 JNI ? JNI (Java Native Interface) 是 Java 沟通 Native 语言(主要是C、C++)的桥梁。 Native 语言有着更高的性能,更重要的是还有庞大的 Native 语言所编写的库。 这些给 Java 语言提供很多性能优秀的强大功能支持。 JNI 能够提供 Java 更快速的 Native 功能移植,也能利用 C++ 的反汇编能力加...

描绘自己的王国…… 390

C++ / JNI - MacOS Java 调用 JNI 保姆级示例

Java 调用 JNI on MacOs 保姆级教程。

BITDDD小栈 1653

【Android -- JNI 和 NDK】JNI 基础知识以及如何使用

我们来系统梳理一下JNI中涉及的基本知识。

Kevin Learn Android 827

jni中多个cpp类的使用

主要完成的功能是使用生成jni对应的Test.h,新建Test.cpp写入内容,再去生成libTest.so,然后在Java类中加载

孤独的糖三角 2602

JNI调用C++方法指南

JNI(Java Native Interface)用来在Java中调用其他语言编写的代码。本文主要介绍如何在Java中调用C++程序。Java中提供了关键字,用于指示方法实现由本地代码来提供。对于C++程序而言,可以将源码打包为静态库或动态库。在JNI中通常使用动态库,这样可以避免将Java字节码和本地代码混合在同一个的二进制文件中。下面通过一个示例来演示JNI的具体用法。步骤1:定义Java类,其源代码如下: 步骤2:通过命令编译Java源文件并自动生成C++头文件,生成的的源码如下: 本地方法声明中

LW的技术小筑 1920

jni总结 .cpp

/************************************JNI_summary_cpp.cpp****************************************************/ /*    *            JNI  总结  *        第二部分  .cpp  *  com.dtBank.app.service  包名

hbzh2008的专栏 1638
上一篇: JNI基础知识(二)C/C++访问Java的成员
下一篇: JNI基础知识(四)C++构造函数及浅拷贝、深拷贝问题
钱多多~吖
博客等级 码龄13年 4粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值