android通过JNI调用C++代码,一头雾水
大家好。被JNI折磨憔悴了。
Java环境下使用JNI调用本地 C/C++ 库我倒研究出了点眉目,就是先定义native,再javah,新建C++项目,拷贝jni.h、jni_md.h,再如此这般。
我C懂点、C++勉强算得上白痴水平。
现在我手头有个android项目,是个视频播放器,有个需求是要实现对指定加密的视频实现解密,解码模块的是C++的实现,代码已经在我手里,是一个".h"和".so"文件。
我已经试了一天,企图将这个C++在Android中使用起来。愣是没成,一直报“ERROR/AndroidRuntime(426): java.lang.UnsatisfiedLinkError: Library libdcry not found”
祈求各路菩萨大慈大悲救我一命。
就是怎样将现有的C++代码,在Android中跑起来。。。。。。。。。
先感谢大伙了!!!
[解决办法]
jni部分是使用c++写的么?
如果是 在JNI里面要 extern "C"{jni c++代码}
[解决办法]
或者在jni里面模仿android的jni
重写jint JNI_OnLoad(JavaVM* vm, void* reserved)方法
[解决办法]
so文件已经生成好了吗,
放在路径 libs/armeabi/下,这样就可直接System.load("so文件名")
[解决办法]
上面某位应该说的是System.loadLibrary方法
java的JNI怎么讲究android的同样也要怎么讲究
[解决办法]
java端定义好对应的native方法(和C++端一定严格对应), System.loadLibrary之后再java端用到什么就调用相应的native方法即可。
[解决办法]
帮顶,没具体研究过jni调用c/C++代码的用法。
你这个是直接找不到库,加载lib的地方难道方法不对?
另外,lib库的静态编译和动态编译有影响吗?
[解决办法]
是不是你的那个.so还要依赖其他的.so,而你没有啊
[解决办法]
ERROR/AndroidRuntime(426): java.lang.UnsatisfiedLinkError: Library libdcry not found
这一句提示很明确了
就是java在调用native的方法时,没有找到这个native方法。
找原因:
1. System.loadLibrary(xxx);
上加try catch,看对不对。
注意System.loadLibrary 和System.load, 括号后面的参数是不一样的。
2. 检查一下,C++中的函数和java中的native方法对应好了没有,有没有漏掉的什么的
3. C++还是自己写Jni_onLoad,给你个例子:
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("GetEnv failed!");
return result;
}
LOG_ASSERT(env, "Could not retrieve the env!");
if(jniRegisterNativeMethods(env, "com/xxx/xxx/xxx",
xxxMethods, NELEM(xxxMethods)) != 0){
LOGE("Register method to com/xxx/xxx/xxxf ailed!");
return -1;
}
return JNI_VERSION_1_4;
}
打印足够的trace,看到底哪里出错了。
JNI实际上是很简单的,与C++关系也不算大。
[解决办法]
android-2.2\development\samples\SimpleJNI
看看源码包的这个目录
还有看看这个文档
http://www.360doc.com/content/10/1012/06/3822981_60261755.shtml
[解决办法]
换了我就只有一个笨方法,
根据头文件重写jni
然后和已有的头文件and .so库
重新编译一个so库出来
[解决办法]
Library libdcry not found
还是库文件没有找到啊,更不要说里面的方法了~看看你把这个文件放的目录对不对,拷贝到其它目录下试试~
[解决办法]
如果拿到的so库是封装好jni的,你看不到他jni封装的格式,你怎么建立对应的java native方法包名,类名呢?同名的java方法对应的jni方法还有不同的签名,参数也不一定是完全对应。
所以还是重新封jni吧
[解决办法]
哥哥来了,
你显然理解错了。人家给你的so并非你可以调用的JNI。 你必须重新封装别人给你的方法,然后提供本地java代码。
因为他提供给你的不过是so,并没有本地方法,比如说liba.so。 你必须自己定义b.cpp和 c.java 在 b.cpp 中写你需要的方法, 然后在c.java 里面装载由b生成的so。并提供和b中对应的java方法。
不知道我这样说你明白没有,另外很久没有来CSDN混分数了。 LZ你懂得
[解决办法]
[解决办法]
给so文件命名时也得按照这个标准
[解决办法]
你有没有c的代码,如果有,要按你的java工程修改c中的工程名,
例如:
com.btrend.android.decdivx对应的c中是com_btrend_android_decdivx_DecDivx
如果没有,调用成功的可能性几乎是0
[解决办法]
检查是否把所有的动态库放进去以及是否放对地方了。
[解决办法]
例子 so文件名称叫 libJicmp.so
java代码:System.loadLibrary("Jicmp");
.so文件叫动态链接库文件, 其实相当于java里的jar文件的含义.
在linux底下可以放到 LD_LIBRARY_PATH环境变量对应的目录下 在android下不太清楚是哪个目录下
报哪个错误的原因有两个:
1.你的文件没放对地方
2.地方放对了,但是还有一个原因, c/c++是不夸平台的,就是说 你的.so文件是不是在别的操作系统环境下编译的,就比如同样都是linux系统,在redhat下编译的.so文件放到其他linux下不一定能用。这种情况就需要你用源码重新编译后使用
[解决办法]
#25 就是说得太简单了点,不过看起来楼主已经明白了
(下面是一个满足 JNI 一个接口的例子)
extern "C" // 假定 JNI 代码是 C++ ,需要这一行
JNIEXPORT jint JNICALL Java_com_xxx_socket_InitConnect
(JNIEnv *env, jobject obj, jint nClient, jint port, jstring strIP);
对应的 Java 代码,必须是 src/com/xxx 目录下的 socket.java 文件中的
public class socket 中的
public native static int InitConnect(int nClient, int port, String strIP);
函数