使用C++编写Jni库进行总结

44 篇文章 1 订阅 ¥9.90 ¥99.00
本文详细介绍了如何使用C++编写JNI库,包括Java包处理、DLL路径、参数调用,C++的JNI头文件路径、字符串转换、Java对象处理,以及Java编译和函数返回类型等关键点,帮助开发者深入理解JNI的实践应用。
摘要由CSDN通过智能技术生成
一。Java问题
1). package问题
网上的例子大部分都有package edu.netcom.jni;,编译时使用:javah package edu.netcom.jni
这是java package,不一定要照用,可使用简短的package,例如: Jni
2). C++ dll路径问题
C++编写的dll只需要放在java源码同一目录即可
3). 调用参数问题
Jni不能使用传出参数,只能通过返回值来传回结果,可传递数据,对象,对象数组(object[])

二。C++问题
1)。Jni包含路径问题
使用 $(JAVA_HOME)\include\win32  $(JAVA_HOME)\include
2)。字符串问题
java与C++使用的字符需要进行转换,特别是中文字符
3)。Java.String类型属性问题
例子:jfieldID fieldName = pJniEnv->GetFieldID(classServInfo, "strName", "Ljava/lang/String;");
4)。返回对象问题
函数返回单个对象,可使用Jni导出函数第二个参数jobject类型参数构造对象,也可定义新的返回对象,例

子:
jobject objRes = 0;
objRes = pJniEnv->AllocObject(classLoginResult);
5)。返回对象数组问题
函数返回对象数组,不能使用Jni导出函数第二个参数jobject类型参数构造对象,否则数组中的对象为同一

个对象,例子:
jobjectArray objArrayRes = 0;
//获取object所属类,一般为ava/lang/Object
jclass objClass = pJniEnv->FindClass("java/lang/Object");

// 获取java对象
jclass classServInfo = pJniEnv->FindClass("SOVJni/SOVGameServerInfo");

// 获取SOVGameServerInfo属性
jfieldID fieldId = pJniEnv->GetFieldID(classServInfo, "sId", "S");
jfieldID fieldName = pJniEnv->GetFieldID(classServInfo, "strName", "Ljava/lang/String;");
jfieldID fieldStatus = pJniEnv->GetFieldID(classServInfo, "cStatus", "B");

// 2008-09-10 得到类的构造函数
jmethodID mtdConstruct = pJniEnv->GetMethodID(classServInfo, "<init>", "()V");

// 构造对象数组
objArrayRes = pJniEnv->NewObjectArray(sServCount, objClass, 0);

// 构造多个对象
for (int s = 0; ; )
{
// 2008-09-10 java调用出现内存访问错误,原因是AllocObject
// jobject objServ = pJniEnv->AllocObject(classServInfo);
jobject objServ = pJniEnv->NewObject(classServInfo, mtdConstruct);

pJniEnv->SetShortField(objServ, fieldId, rServInfo.sId);
jstring strName = JStringConvert::WindowsToJString(pJniEnv, rServInfo.arName);
pJniEnv->SetObjectField(objServ, fieldName, strName);
pJniEnv->SetByteField(objServ, fieldStatus, rServInfo.cStatus);
pJniEnv->SetObjectArrayElement(objArrayRes, s, objServ);
}
三 。Java编译
可使用如下bat命令来编译Java程序,得到导出的C++接口
@if "%1" == "" goto error_1
@if "%1" == "/?" goto help
@if "%1" == "/help" goto help
@if "%2" == "" goto error_2

rem:进入目录
@cd %~p1
@cd %~d1

rem:编译%~n1%~x1文件
javac -d . %~n1%~x1

rem:生成C++接口文件%2.%~n1.h
javah %2.%~n1

@cd %~d1\
@goto end

:error_1
@echo "请输入要编译的java文件完整路径。"
goto end

:error_2
@echo "请输入Jni库的package名。"
goto end

:help
@echo JNICompare.bat 参数1 参数2 参数3
@echo 参数1 -- 要编译的java文件完整路径
@echo 参数2 -- java文件的package名
@echo 参数3 -- 其它命令,例如: exit

:end
%3

2008-09-10
四。AllocObject与NewObject
调用AllocObject产生jclass类定义对应的类实例对象;这不会调用任何类的构造函数,仅仅是内存创建。
调用NewObject产生jclass类定义对应的类实例对象;这需要提供类的构造方法的MethodID,会调用指定的

MethodID对应的构造函数。

五。java对象的构造函数
构造函数作为特例,方法名字为 <init>,返回类型为 ()V

C++获取 java对象构造函数的例子:
jmethodID mtdConstruct = pJni->GetMethodID(cls, "<init>", "()V");      

六。函数返回类型
Java类型       对应的签名
boolean            Z
byte              B
char              C
shrot             S
int               I
long               L
float              F
double             D
void               V
Object           L用/分割包的完整类名;  Ljava/lang/String;
Array           [签名       [I       [Ljava/lang/String;


七。javap命令
调用GetStaticMethodID获取jclass类定义指定类静态方法的MethodID;需要提供静态方法的名字和参数表

信息。这可以通过 jdk内置的命令 javap -s -c 类名字(不含class扩展名) 得到。
调用CallStatic<Type>Method执行指定MethodID对应的类的静态方法,其中<Type>应替换为函数返回值类

型的描述.如CallStaticIntMethod完成调用所有的返回值为Int的类的静态方法.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值