android通过JNI调用C++代码,一头雾水

wenlin56 2011-01-20 11:04:10
大家好。被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中跑起来。。。。。。。。。


先感谢大伙了!!!
...全文
5297 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
weishanwei 2012-08-17
  • 打赏
  • 举报
回复
添加libs 文件夹 再在此文件夹下新建armeabi 文件夹 再将.so文件拷贝到此文件目录下。
arpsyalin 2012-04-26
  • 打赏
  • 举报
回复
public class TestJNI extends AndroidTestCase {
static {
System.loadLibrary("libdcry");
}

public native String _readFile();
public void testJNI() {
_readFile();
}
}

我是新手本来不想说的怕误导人。
但是一个帖子直到看了30楼觉得还是有跟我想法一样的人就呼应一下。
我记得昨天看google jni用法的时候里面有说 libXXXX.so文件 lib是生成.so文件的时候自己添加的。
在java里面System.loadLibrary的时候就不要加lib。System.loadLibrary("XXX");
s06221098 2011-12-29
  • 打赏
  • 举报
回复
那个.so不是交叉编译生成的,所以不能直接调用,要重新封装
TechStone 2011-10-09
  • 打赏
  • 举报
回复
报“Library libdcry not found”是连库都没找到,先不用分析函数名啊,编译环境之类的。如果是编译环境的问题,会报“wrong ELF”错误。

所以先看System.loadLibrary的参数对不对吧。

如果别人只提供一个so库而且这个库没有用符合JNI的标准来写的话,还需要自己再写一个so来调用这个库里面的函数,还有个前提是别人提供的so库用的编译器跟设备的环境相符合(应该是arm吧)。
fredhurui 2011-09-22
  • 打赏
  • 举报
回复
请在java中申明native函数public native int add(int a, int b);
在c文件中定义的函数名字应该形如:
jint Java_com_test_hellojni_HelloJni_add(JNIEnv *evn, jobject this, jint a,
jint b) {

return a + b;
}
项目组织结构:
HelloJni
/ | \
src jni AndroidManifest.xml
/ / \
com Androi.mk hello.c
/
test
/
hellojni


Android.mk文件内容如下:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)

------------------------------------
你需要进入jni源码所在目录*/HelloJni/jni 运行: $NDK/ndk-build产生lib文件
----------------------------------------
在java中load library
static {
System.loadLibrary("hello-jni");
}
yinyongcom666 2011-06-13
  • 打赏
  • 举报
回复
SO库必须是用NDK编译的,用GCC可不行,所以没有源代码就白扯
阿丘-XM 2011-05-05
  • 打赏
  • 举报
回复
没有源码 你只有第三方的so和h,怎么再生成so?

要有源码
duanlonglong1 2011-04-25
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 ayuppie 的回复:]
先好好研究下jni如何实现。android和平常的有点点区别。
要定义如下这个结构体。参考android_media_mediaPlayer.cpp
static JNINativeMethod gMethods[] = {
{"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaPlayer_setDa……
[/Quote]
hackkuang001 2011-02-22
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 ayuppie 的回复:]
先好好研究下jni如何实现。android和平常的有点点区别。
要定义如下这个结构体。参考android_media_mediaPlayer.cpp
static JNINativeMethod gMethods[] = {
{"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaPlayer_setDa……
[/Quote]
上面的更加深入到jni了用了方法的隐射不用写难看的jni头了
ayuppie 2011-01-31
  • 打赏
  • 举报
回复
先好好研究下jni如何实现。android和平常的有点点区别。
要定义如下这个结构体。参考android_media_mediaPlayer.cpp
static JNINativeMethod gMethods[] = {
{"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaPlayer_setDataSource},
{"setDataSource", "(Ljava/lang/String;Ljava/util/Map;)V",(void *)android_media_MediaPlayer_setDataSourceAndHeaders},
{"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
stonecao 2011-01-29
  • 打赏
  • 举报
回复
来混点分数:
jni我以前也写过一个例子,在学习core java的时候,楼主可以这么入手去解决这个问题:
1.写一个native方法类,用javah生成它的c存根,完成一个java到c调用的例子
2.实现c存根方法调用c++模块代码的的调用
以上两步分开来做会很简单,各个击破,不要一入手就想把它给搞定
lazy_2010 2011-01-29
  • 打赏
  • 举报
回复
#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);

函数

netlib 2011-01-28
  • 打赏
  • 举报
回复
你有没有c的代码,如果有,要按你的java工程修改c中的工程名,
例如:
com.btrend.android.decdivx对应的c中是com_btrend_android_decdivx_DecDivx

如果没有,调用成功的可能性几乎是0
wenlin56 2011-01-28
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 gezexu 的回复:]

给so文件命名时也得按照这个标准
[/Quote]
Thank you
ouch1985 2011-01-28
  • 打赏
  • 举报
回复
例子 so文件名称叫 libJicmp.so
java代码:System.loadLibrary("Jicmp");

.so文件叫动态链接库文件, 其实相当于java里的jar文件的含义.
在linux底下可以放到 LD_LIBRARY_PATH环境变量对应的目录下 在android下不太清楚是哪个目录下

报哪个错误的原因有两个:
1.你的文件没放对地方
2.地方放对了,但是还有一个原因, c/c++是不夸平台的,就是说 你的.so文件是不是在别的操作系统环境下编译的,就比如同样都是linux系统,在redhat下编译的.so文件放到其他linux下不一定能用。这种情况就需要你用源码重新编译后使用
susemm 2011-01-28
  • 打赏
  • 举报
回复
检查是否把所有的动态库放进去以及是否放对地方了。
北漂 2011-01-26
  • 打赏
  • 举报
回复
给so文件命名时也得按照这个标准
北漂 2011-01-26
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wenlin56 的回复:]
引用 4 楼 yuhuaijun 的回复:

so文件已经生成好了吗,
放在路径 libs/armeabi/下,这样就可直接System.load("so文件名")

提示“Library libdcry not found” —— 找不到
[/Quote]
System.loadLibrary("lib" + 库名 + ".so");
android加载的本地库,一定是以lib开头,.so为后缀的,中间是你的库名
guzhijie1981 2011-01-24
  • 打赏
  • 举报
回复
哥哥来了,
你显然理解错了。人家给你的so并非你可以调用的JNI。 你必须重新封装别人给你的方法,然后提供本地java代码。

因为他提供给你的不过是so,并没有本地方法,比如说liba.so。 你必须自己定义b.cpp和 c.java 在 b.cpp 中写你需要的方法, 然后在c.java 里面装载由b生成的so。并提供和b中对应的java方法。


不知道我这样说你明白没有,另外很久没有来CSDN混分数了。 LZ你懂得
work_acc 2011-01-21
  • 打赏
  • 举报
回复
如果拿到的so库是封装好jni的,你看不到他jni封装的格式,你怎么建立对应的java native方法包名,类名呢?同名的java方法对应的jni方法还有不同的签名,参数也不一定是完全对应。
所以还是重新封jni吧
加载更多回复(21)

80,349

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧