Windows控件调用错误下,Android Studio中如何在C++代码中调用第三方so文件,我的调用没有发现第三方so,求帮忙解答

Android导入第三方静态库.a编译成动态库.so_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Android导入第三方静态库.a编译成动态库.so
来源:Linux社区&
作者:ikinglai
在开发的时候,经常会使用到用c或c++编写的第三方的静态库。如果有源码的话,可以直接跟你自己的代码一去编译成动态库so,但是如果没有源码的话,你就必须在自己的动态库so里面将别人生成好的静态库导入进来一起编译了。我在编译的时候遇到了不少问题,我觉得有必要进行总结一下。
下面我以一个简单的实际例子来讲解如何在动态库中导入静态库。
静态库中的源代码有两个文件:static.h, static.c,有一个add方法
static.h#include &stdio.h& int add(int x, int y);
static.c#include "static.h" int add(int x, int y) { & & return x + }
将它编译成静态库,Android.mk如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE& & := static_add LOCAL_SRC_FILES := static.c include $(BUILD_STATIC_LIBRARY)
注意编译静态库的时候,必须有一个Application.mk文件:
APP_MODULES:=static_add
APP_MODULES的值应该和Android.mk中的LOCAL_MODULE的值保持一样。
然后调用ndk-build进行编译生成libstatic_add.a静态库。
hejinlai_iMac:jni hejinlai$ ndk-buildPrebuilt : libstatic_add.a &= jni/
生成静态库后,然后编写动态库中的源代码: share.h share.cshare.h#include &stdio.h& int test_add(int x, int y);
share.c1234567 #include "share.h"#include "static.h"int test_add(int x, int y) { & & // 调用static里面的方法 & & return add(x, y); }
编写导入静态库的Android.mk:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE& & := static_add LOCAL_SRC_FILES := libstatic_add.a include $(PREBUILT_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE& & := share_add LOCAL_STATIC_LIBRARIES := static_add LOCAL_SRC_FILES := share.c include $(BUILD_SHARED_LIBRARY)
注意上面生成的libstatic_add.a必须跟Android.mk放在同一目录下,否则需要填写相应的路径,然后进行编译:
hejinlai_iMac:jni hejinlai$ ndk-buildCompile thumb : share_add &= share.cPrebuilt : libstatic_add.a &= jni/SharedLibrary : libshare_add.soInstall : libshare_add.so =& libs/armeabi/libshare_add.so
提示so编译成功。
需要注意的是我这边share.c和static.c放在同一目录下,如果放在不同的目录下,需要指定
LOCAL_C_INCLUDES链接到相应的路径。
推荐阅读:
使用hello-gl2建立NDK-gdb环境(有源码和无源码调试环境)
基于Android NDK开发实践案例解析
解决不使用Android NDK编译的bin文件No such file or directory问题
Android NDK :编写清晰的代码结构
Android开发教程:NDK编译静态库失败
更多Android相关信息见 专题页面
相关资讯 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款&nbsp>&nbsp
&nbsp>&nbsp
&nbsp>&nbsp
Android Studio2.2.3使用C++生成so文件
之前的时候写过AndroidStudio2.2.3之前的so库文件,之前的版本的so库文件的编写详见,之前写过的文章:http://blog.csdn.net/wb175208/article/details/当再次使用的时候,发现很多问题,之前使用已经不能成功了。原来是AndroidStudio升级后能很好的兼容C++,包括语法检测、自动生成函数的头文件等多种功能。自己在尝试包括在网上查找资料后,包使用方法写出来,以备之后使用。1.创建一个工程,注意一定
之前的时候写过Android Studio2.2.3之前的so库文件,之前的版本的so库文件的编写详见,之前写过的文章: http://blog.csdn.net/wb175208/article/details/
当再次使用的时候,发现很多问题,之前使用已经不能成功了。原来是Android Studio升级后能很好的兼容C++,包括语法检测、自动生成函数的头文件等多种功能。自己在尝试包括在网上查找资料后,包使用方法写出来,以备之后使用。 1.创建一个工程,注意一定要勾选上这个Include C++ Support
2.一路点击 【next】点击到最后的时候,采用默认就好了:
3.点击【finish】之后,会报错:NDK not configured
4.右键点击工程名称:open moudule setting
5.把我们提前下载好的NDK,配置上去就可以了,点击【OK】
6.里面已经为我们生成了一个Demo,可以直接运行看看结果,里面有cpp,仅供参考:
还可以找到我们生成的so文件
7.但是呢,很多时候我们是不用demo的,我们需要自己手写自己的.h和.cpp文件。那我们就修改一下原来的文件。首先修改生成的so的名称和链接使用的名称:把原来的native-lib改为TestCpp
8.新建一个本地类文件TestCpp.java,并且引用我们新建的so库,红色报错也不要着急
点击Ctrl+E,选择第一个AS会自动帮我们生成实现
9.下面我们就直接测试一下看看是不是我们想要的结果。so文件我们需要release版本的。PS:(Debug版本和release版本,做个C++的都知道。debug版本是调试的使用的,里面包含很多的调试信息,文件体积也是比较大;release版本发布的时候使用的,会自动的去除掉里面的调试信息,文件体积比较小)。通过Gradle projects生成release版本:
然后在这个位置就可以找到我们的release版本的so文件
10.新建一个module来测试我们生成的so文件,然后把我们需要的so文件和TestCpp拷贝测试module中: 注意:TestCpp包名路径名必须和原来的保持一致
还需要添加这部分内容:
11.查看效果:
这样就已经到达我们需要的效果了。 12.但是C++是需要.h文件和.cpp文件配合之后的,如果我要添加新的c++类怎么办呢? 那我们就添加一个C++类: Test.h //// Created by aaa on .//#ifndef LATINIME_TEST_H#define LATINIME_TEST_H#include &string&class MyTest {public: int testAdd(int a, int b); std::string get_str();};#endif //LATINIME_TEST_H
Test.cpp //// Created by aaa on .//#include &Test.h&std::string MyTest::get_str() { return &asdsgfdshgf&;}int MyTest::testAdd(int a, int b) { return a +}
添加一个native-lib.h文件 //// Created by aaa on .//#ifndef LATINIME_NATIVE_LIB_H#define LATINIME_NATIVE_LIB_H#include &jni.h&#include &string&#include &Test.h&#ifdef __cplusplusextern &C& {#endifextern MyTest gTJNIEXPORT jstring JNICALL Java_com_ime_aaa_testcplus_TestCpp_testGetString(JNIEnv *env, jclass type, jstring str_);JNIEXPORT jint JNICALL Java_com_ime_aaa_testcplus_TestCpp_testAdd(JNIEnv *env, jclass type, jint a, jint b);#ifdef __cplusplus}#endif#endif //LATINIME_NATIVE_LIB_H
native-lib.cpp #include &native-lib.h&//定义一个全局变量MyTest gT/** * C字符串转java字符串 */jstring strToJstring(JNIEnv *env, const char *pStr) { int strLen = strlen(pStr); jclass jstrObj = env-&FindClass(&java/lang/String&); jmethodID methodId = env-&GetMethodID(jstrObj, &&init&&, &([BLjava/lang/S)V&); jbyteArray byteArray = env-&NewByteArray(strLen); jstring encode = env-&NewStringUTF(&utf-8&); env-&SetByteArrayRegion(byteArray, 0, strLen, (jbyte *) pStr); return (jstring) env-&NewObject(jstrObj, methodId, byteArray, encode);}/** * jstring -& UTF-8 */char *jstringToUTF8(JNIEnv *env, jstring jstr) { char *rtn = NULL; jclass clsstring = env-&FindClass(&java/lang/String&); jstring strencode = env-&NewStringUTF(&utf-8&); jmethodID mid = env-&GetMethodID(clsstring, &getBytes&, &(Ljava/lang/S)[B&); jbyteArray barr = (jbyteArray) env-&CallObjectMethod(jstr, mid, strencode); jsize alen = env-&GetArrayLength(barr); jbyte *ba = env-&GetByteArrayElements(barr, JNI_FALSE); if (alen & 0) { rtn = (char *) malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env-&ReleaseByteArrayElements(barr, ba, 0);}JNIEXPORT jstring JNICALLJava_com_ime_aaa_testcplus_TestCpp_testGetString(JNIEnv *env, jclass type, jstring str_) { char *ch = jstringToUTF8(env, str_); return env-&NewStringUTF(ch);}JNIEXPORT jint JNICALLJava_com_ime_aaa_testcplus_TestCpp_testAdd(JNIEnv *env, jclass type, jint a, jint b) { return gTest.testAdd(a, b);}
并且修改CMakeLists.txt文件,把我们需要编译的文件添加进去
13.重新编译so库文件,拷贝到测试的module中,并且修改TestCpp.java文件
以上是的内容,更多
的内容,请您使用右上方搜索功能获取相关信息。
若你要投稿、删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员会在五个工作日内给你回复。
新用户大礼包!
现在注册,免费体验40+云产品,及域名优惠!
云服务器 ECS
可弹性伸缩、安全稳定、简单易用
&40.8元/月起
预测未发生的攻击
&24元/月起
你可能还喜欢
你可能感兴趣
阿里云教程中心为您免费提供
Android Studio2.2.3使用C++生成so文件相关信息,包括
的信息,所有Android Studio2.2.3使用C++生成so文件相关内容均不代表阿里云的意见!投稿删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员会在五个工作日内答复
售前咨询热线
支持与服务
资源和社区
关注阿里云
InternationalAndroid JNI找不到第三方库的解决方案 cannot load library
最近做一个jni项目,拿到的so库需要用jni封装一层,等于是在jni的C++代码里调用第三方库的方法,然后整个项目在上运行出结果。
自己用jni生成的so是libaa.so 使用的第三方库是libbb.so。
到目前为止,遇到的问题是libbb各种找不到。libbb库去哪儿了?
E/AndroidRuntime(11626): Caused by: java.lang.UnsatisfiedLinkError:
Cannot load library: soinfo_link_image(linker.cpp:1640):
could not load library libbb.so needed by libaa.
caused by load_library(linker.cpp:750): library libbb.so not found
以上错误是在运行阶段发生的,事实上编译阶段也发生过找不到第三方的问题,表现就是库里实现的方法undefined。
分两方面解决
1,编译阶段找不到库,需要修改MK文件。
1.libbb.so放在jni/prebuilt文件夹(自己新建),同时把Android.mk复制一份到prebuilt下。
2.libbb.so的mk如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := bb
LOCAL_SRC_FILES := libbb.so
include $(PREBUILT_SHARED_LIBRARY)
3.libaa.so的mk文件需要引入上面的mk。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE
LOCAL_SRC_FILES := aa.cpp
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := bb
include $(BUILD_SHARED_LIBRARY)
include $(LOCAL_PATH)/prebuilt/Android.mk
这样在编译阶段就可以连接到第三方库咯。
2.运行阶段找不到库
在运行阶段找不到库就是Android的事情了。后来发现是load库的顺序(默哀一个,破顺序。。)。
System.loadLibrary(bb);
System.loadLibrary(aa);
先load第三方库,再load自己的库,因为aa库要用bb库里的方法,是依赖于bb库的,所以要先load。。
这样在运行阶段也可以找到库咯。一.Android平台如果要调用一些C/C++语言的所编译生成的库的函数一般要进行一下几个步骤。
1.确保我们的so库是用 ndk 或者 arm-linux-androideabi-gcc编译而成,如何编译参考上一篇文章。
2.如果我们的安卓应用程序是在studio中开发用java所写,那么我们 需要配置以下内容:
去Android官网下载NDK并配置到我们的studio中,gradle.properties文件中加上一句:
android.useDeprecatedNdk=true //不加有可能导致编译不成功
因为我们是用java调用c/c++,需要我们需要使用jni,创建一个类并实现Jni规范中本地方法
public class NdkTest {
System.loadLibrary("NdkTest");
//我们要生成的so库的名字,前缀和后缀名去掉
public static native String myAdd(); //我们java调用c所实现的jni方法,我们要做的就是在这个jni函数中去调用没有jni规范的c/c++函数
c:在studio这rebuild,为这一个类生成.class文件
d:调用jdk中的javah,为这个.class文件生成一个.h文件
e:在我们app目录下创建jni文件夹,将.h文件放入,并创建.c或者.cpp文件去实现我们的.h中的函数,在这些函数中我们就可以调用第三方的so库了
f:将第三方so或者第三方的c源码及我们的.h一同放入jni目录下,并书写Android.mk 及
Application.mk文件,进行编译规程的书写,至于如何写mk文件,可以参考上一篇文章或者自行百度,有海量的资料。
g:书写过mk文件之后我们可以直接在stdio下调用命令行进行ndk-build编译,会在libs目录下生成.so文件,注意我们studio默认寻找的路径是jnilibs,如果不想改gradle的话可以直接在jni下创建jnilibs目录,将.so放入,这是一个坑,一定要注意。
h:编译完成以后我们就可以直接在类中直接调用我们刚开始定义的native方法进行与c语言的通信了。
3.如果我们的Android应用是在qt中用c++开发的话,因为没有涉及到jni,所以简单很多:
a: 将用我们编译好的so库直接在pro文件中LIB中进行引用,或者直接调用项目,在build apk 选项中,有add library中进行添加。
b:将.h在.pro中进行引入。
c:直接在.cpp中直接调用就可以了。
e:没事了,就是这么方面。
二: 碰到的一些坑
1.在我们jni实现的函数中如果去调用so中的函数,一定要用dlopen、dlsym、dlclose去查找so及加载so中的函数,切记切记,我在这上面吃了很大的亏。
2.利用javah生成.h文件的时候,一定要 cd到你Android工程的bin/classes目录下,包含完整类名,不带.class。
3.加载so的顺序一定要注意,一定要注意。
4.注意一些jni类型的数据的转换。
Qt on Android调用so库的问题
Qt on Android调用so库的问题
Qt on Android调用so库的问题------
觉得很有用,收藏!
来源:Qt on Android调用so库的问题
一:桌面引用dll库的一般方法:
在windows在用QrCreaotr开发dll库并使用...
apk调用so库的问题
为了方便说话,先来几个定义。
用户自己手动安装的程序,称为第三方程序。
编译系统时,源码放在packages下面生成的程序,称为系统程序。
/system/lib/下的so库称为系统库
android源码编译apk集成第三方so库
一般编译android应用,生成apk,有以下几个方法:
1.传统的在eclipse平台下编译生成apk,这种情况下,需要指定android sdk,通过eclipse编译生成apk,编译的...
android工程添加第三方库.so文件
安卓native项目,接入sdk的时候,当第三方库中包含.so文件,我们把.so文件放到安卓工程的armeabi,armeabi-v7a 等文件夹下面的时候,然后再运行该项目,编译的时候,是会删掉对应...
Android NDK编译中在libs\armeabi中加入第三方so库文件的方法
转载自:http://blog.sina.com.cn/s/blog_727bd1560101gmdh.html
假设要加入库文件的名字为libffmpeg.so文件
1.要在project\jn...
android studio使用第三方so文件
1、so文件放到工程的libs目录下2、build.gradle文件android {
compileSdkVersion 23
buildToolsVersion &23....
Android平台下JNI调用第三方so库
首先说一下在网上查找资料时,对于调用第三方so库,有人说有两种方法:
对于so库的API符合JNI格式(即使用javah指令生成的头文件中那种格式),可以在Java代码中声明它对应的...
android 调用第三方so库
首先要知道这个第三方的so库是不是按jni标准写的,如果是那就简单了,直接写个native调用就行了。如果不是那就比较麻烦了,必须要把这个so库里面的函数封装一下在调用,下面进入正题。假设这个库放在/...
Android Studio中的Android项目调用第三方库so库
Android NDK开发中,除了可以通过自己编写C/C++代码来构建动态连接库进行调用之外,还可以通过直接调用现成的so库开进行NDK开发。接下来,我将介绍在Android Studio中如何调用第...
没有更多推荐了,Android studio 编写NDK小项目,在写C++代码时 不识别 jint 类型 怎么解决?_百度知道
Android studio 编写NDK小项目,在写C++代码时 不识别 jint 类型 怎么解决?
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
采纳数:142
获赞数:3314
擅长:暂未定制
新建项目时,勾选Include C++ Support
采纳数:19
获赞数:16
#include&jni.h&; 这个在JAVA SdK目录下面有的。。自己找
具体怎么操作 啊
申明这个头文件也不好使啊
引入这个头文件。不是申明。就像你包含stdlib.h一样。还有就是。你要把这个头文件的目录加到你的项目中。要不然也找不到。
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 Windows控件调用错误 的文章

 

随机推荐