
是的,jni调用时, java和c是同个线程。
检测方法:在java和c中分别把当前线程的id输出出来查看。
Java获取线程Id:
ThreadcurrentThread()getId();C中获取线程Id:
GetCurrentThreadId();应该是你调用C/C++函数写的有点问题,你可以写一个测试函数,例如:
JNIEXPORT int JNICALL Java_(包名)_(类名)_test(JNIEnv env, jobject thiz)
{
return 102;
}
测试一下,打印出来,如果有结果,说明,你的dll生成和调用都是没有问题的,然后设置断点,单步执行,就可以知道具体是哪一个JNI函数内部的问题了。
1
在交叉编译的时候怎么都无法生成so文件,javah生成头文件没错,c文件也没错,java文件也没错,
2原因:是JNI文件夹路径不对
3
在执行javah命令时,我进入的是cd
app/src/main/java
这样jni文件夹在java文件夹下,作为一个包存在,这样就无法生成so文件
执行javah的正确姿势:
4
进入app/src/main目录:cd
app/src/main
执行javah命令:javah
javah
-d
jni
-classpath
/Java
labsodinojnitestMainActivity
5,
-d
jni
头文件生成到jni文件夹(当前在<Project>\app\src\main目录下,所以h所在的目录为<Project>\app\src\main\jni
)
-classpath
/java
指定去当前路径下java下寻找包名指定的类
这样再rebuild一下,就会生成so文件了
前一段时间 我用java开发一个安装程序 适用于tomcat mysql构建的web环境 在开发的过程中遇到与写注册表 注册系统服务等问题用java本身很难解决 于是我想到用JNI C与delphi两者开发JNI 我是从delphi转到java上来的 我选择了delphi
用delphi开发JNI 首先从//delphi jedi下载JNI pas 把它加入到工程中就可以开发JNI了
例如创建桌面快捷方式:
Delphi中的代码:
library myDllusesJNI windows ComObj ActiveX ShlObj SysUtils Registry;//取得桌面目录function getDesktopPath():String;varReg:TRegistry;DesktopPath:String;beginReg:=TRegistry Create;tryReg RootKey:=HKEY_CURRENT_USER;Reg OpenKey( Sofare\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders False);if Reg ValueExists( Desktop ) then DesktopPath:=Reg ReadString( Desktop );Result:= DesktopPath;finallyReg Free;end;end;//创建桌面快捷方式procedure CreateDesktopLink(ProgramPath ProgramArg LinkName Descr IconPath: String);varAnObj: IUnknown;ShellLink: IShellLink;AFile: IPersistFile;FileName: WideString;LinkPath:String;beginLinkPath:=getDesktopPath()+ \ +linkName;if UpperCase(ExtractFileExt(LinkPath))<> LNK then //检查扩展名是否正确beginraise Exception Create( 快捷方式的扩展名必须是 lnk! );end;tryOleInitialize(nil);//初始化OLE库 在使用OLE函数前必须调用初始化AnObj := CreateComObject(CLSID_ShellLink);//根据给定的ClassID生成一个对象 此处是快捷方式ShellLink := AnObj as IShellLink;//强制转换为快捷方式接口AFile := AnObj as IPersistFile;//强制转换为文件接口//设置快捷方式属性 此处只设置了几个常用的属性ShellLink SetPath(PChar(ProgramPath)); // 快捷方式的目标文件 一般为可执行文件ShellLink SetArguments(PChar(ProgramArg));// 目标文件参数ShellLink SetWorkingDirectory(PChar(ExtractFilePath(ProgramPath)));//目标文件的工作目录ShellLink SetDescription(PChar(Descr));// 对目标文件的描述ShellLink SetIconLocation(PChar(IconPath) );FileName := LinkPath;//把文件名转换为WideString类型AFile Save(PWChar(FileName) False);//保存快捷方式finallyOleUninitialize;//关闭OLE库 此函数必须与OleInitialize成对调用end;end;//创建桌面快捷方式 在JNI中调用的就是这个方法//这个过程的命名很有讲究 它以 Java 开头 用下划线将 Java 类的包名 类名和方法名连起来 这个命名方法不能有误 否则 Java 类将无法将 nativ 方法与它对应起来 同时 在 Win 平台上 此过程的调用方式只能声明为 stdcall procedure Java__wpd_JavaWindows_createDesktopLink(PEnv: PJNIEnv; Obj: JObject;ProgramPath ProgramArg LinkName Descr iconPath:JString);stdcall;varJVM:TJNIEnv;PPath:String;PArg:String;LName:String;Description:String;IPath:String;beginJVM := TJNIEnv Create(PEnv);PPath:=JVM UnicodeJStringToString(ProgramPath);PArg:=JVM UnicodeJStringToString(ProgramArg);LName:=JVM UnicodeJStringToString(LinkName);Description:=JVM UnicodeJStringToString(Descr);IPath:=JVM UnicodeJStringToString(IconPath);CreateDesktopLink(PPath PArg LName Description IPath);JVM Free;end;//向java发送一个信息function Java__wpd_JavaWindows_sendMessage(PEnv: PJNIEnv; Obj: JObject):JObject;stdcall;varJVM:TJNIEnv;msg:JObject;m:String;beginJVM := TJNIEnv Create(PEnv);//如果发送的信息中包含中文字符 则要先要经过UTF Encode转码 否则在java中取得时会是乱码m:=UTF Encode( 中国人 );msg:=JVM StringToJString(PChar(m));result:= msg;end;{$R res}exportsJava__wpd_JavaWindows_createDesktopLink Java__wpd_JavaWindows_sendMessage;end
把上面的编译生成myDll dll文件 放到java能够找到的地方
java中的代码:
lishixinzhi/Article/program/Java/hx/201311/27225
AndroidStudio怎么调用so动态链接库?在我们日常开发中,经常会用到一些复杂的加密的算法以保证通信的安全。通常这些算法会用C或C++实现后打包成so动态链接库并向Java层开发接口方便调用。
以AndroidStudio为例
1 首先去下载NDK包,下载路径如下可根据自己系统定点下载
>
2 创建一个安卓工程,初始化完成以后,右键项目->Open Module Settings
选择你下载的ndk存放路径
3 创建一个jniTest类,写好navite方法,点击Build->Make Project打包文件
4 点击底下的Terminal窗口 cd 到当前项目目录
例:当前目录为JniDemo C:\Users\bilibili\Desktop\JniDemo>
cd C:\Users\bilibili\Desktop\JniDemo\app\build\intermediates\classes\debug
调用命令javah -jni 包名类名生成头文件(文件生成在以上cd定位到的目录)
5 在main>src下创建文件夹jni(new-Folder-jni Folder)进目录app>build>intermediates>classes>debug旗下找到头文件复制到jni文件夹
6 jni目录下生c文件与h文件重名c文件编写如下:
JNIEXPORT jstring JNICALL Java_com_jni_jnidemo_JniText_get_11111CLang_11String(JNIEnv env, jobject obj){
return (env)->NewStringUTF(env,"This just a test for Android Studio NDK JNI developer!");
}
7 在app的buildgradle的defaultConfig标签下添加如下标签:
ndk{moduleName "jnitext" //生成的so名字,根据你自己的so定义
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。目前可有可无。
}
8 在工程的gradleproperties添加如下代码:
androiduseDeprecatedNdk=true
9 点击Build->Make Project打包文件,去\app\build\ndk\debug\lib\目录下拷贝编译好的so文件复制到app\libs目录下即可
10 调用如下:
static {SystemloadLibrary("jnitext");
}
public native String get_1111CLang_1String();
你这样直接转换是不行的JNIEXPORT jbyteArray JNICALL Java_Test_getByteArray(JNIEnv env, jobject obj){jbyteArray firstMacArray = env->NewByteArray( 6 );elidedjbyte bytes = env->GetByteArrayElements( firstMacArray, 0);for ( int i = 0; i < sizeof( pAdapterInfo->Address ); i++ ){bytes[ i ] = pAdapterInfo->Address[ i ];}env->SetByteArrayRegion(firstMacArray, 0, 6, bytes );return firstMacArray;}另外,给你一个有关各种转换的博客 >
以上就是关于jni调用 java和c是同个线程吗全部的内容,包括:jni调用 java和c是同个线程吗、JNI调用第三方dll报错,求高手帮忙解决,谢谢、android studio JNI开发时 编译成功 但是没有生成.so文件 什么原因等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)