Android Java调用Qt写的so库
有时候,我们反编译apk得到一个so库,如果直接使用这个so库的话,必须使用原来so库同样的package名字,才能用。
这样人家反编译你的apk,就知道你侵犯了人家的版权。为了达到混淆的目的,我们可以再写一个so库调用人家的so库,即把人家的so库放到root的某个路径下,用c/c++语言调用这个so库。比如说,我得到一个APK,反编译这个APK看到下面的代码:
- static {
- try {
- System.loadLibrary("NativeExampleActivity");
- } catch (Throwable t) {
- }
- }
- public native int addFunction(int a, int b);
- public native String getString(String name);
很明显,这个so库是libNativeExampleActivity.so, 库里面有两个native函数addFunction和getString。
虽然知道了这两个native函数,但是我们还不能直接使用,因为这两个native函数在so库里面的真实函数名不是addFunction和getString,
它在native函数名之前还有包名,所以必须使用nm命令,查看so库里面的函数名。
显示so库函数的命令:
nm -A libNativeExampleActivity.so
或者
nm -D libNativeExampleActivity.so
这样我们看到so库里的主要信息:
Java_org_natives_example_NativeExampleActivity_addFunction
Java_org_natives_example_NativeExampleActivity_getString
看到没有,在addFunction函数前面还有包名,这就是为什么直接使用人家的so库的时候,一定要使用原来的package名字!
好了,现在是怎么调用这两个函数了,4个步骤完成。
1.用Eclipse创建一个项目
- package so.hello;
- import android.app.Activity;
- import android.os.Bundle;
- public class SoHelloActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- static {
- try {
- System.loadLibrary("soHello");
- } catch (Throwable t) {
- }
- }
- public native int addFunction1(int a, int b);
- public native String getString1(String name);
- }
2.在终端进入到项目的路径soHello/bin/classes,执行命令:
guo@guo-desktop:~/workspace/soHello/bin/classes$ javah -jni so.hello.SoHelloActivity
在soHello/bin/classes目录下会生成一个文件so_hello_SoHelloActivity.h
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- /* Header for class so_hello_SoHelloActivity */
- #ifndef _Included_so_hello_SoHelloActivity
- #define _Included_so_hello_SoHelloActivity
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * Class: so_hello_SoHelloActivity
- * Method: addFunction1
- * Signature: (II)I
- */
- JNIEXPORT jint JNICALL Java_so_hello_SoHelloActivity_addFunction1
- (JNIEnv *, jobject, jint, jint);
- /*
- * Class: so_hello_SoHelloActivity
- * Method: getString1
- * Signature: (Ljava/lang/String;)Ljava/lang/String;
- */
- JNIEXPORT jstring JNICALL Java_so_hello_SoHelloActivity_getString1
- (JNIEnv *, jobject, jstring);
- #ifdef __cplusplus
- }
- #endif
- #endif
3.写一个so_hello_SoHelloActivity.cpp文件
- #include "so_hello_SoHelloActivity.h"
- #include <stdlib.h>
- #include <fcntl.h>
- #include <android/log.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <dlfcn.h>
- void *filehandle = NULL;
- jint (*addFunc)(JNIEnv *,jobject,jint,jint) = NULL;
- jstring (*getStringFunc)(JNIEnv *, jobject, jstring) = NULL;
- JNIEXPORT jint JNICALL Java_so_hello_SoHelloActivity_addFunction1
- (JNIEnv *env, jobject obj, jint a, jint b);
- {
- jint mun = 0;
- //事先把libNativeExampleActivity放到root/system/lib/目录下
- filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY);
- if(filehandle)
- {
- addFunc = (jint (*)(JNIEnv *,jobject,jint,jint))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_addFunction");
- if(addFunc)
- mun = addFunc(env, obj, a, b);
- dlclose(filehandle);
- filehandle = NULL;
- }
- return mun
- }
- /*
- * Class: so_hello_SoHelloActivity
- * Method: getString1
- * Signature: (Ljava/lang/String;)Ljava/lang/String;
- */
- JNIEXPORT jstring JNICALL Java_so_hello_SoHelloActivity_getString1
- (JNIEnv *, jobject, jstring name)
- {
- jstring mun = 0;
- //事先把libNativeExampleActivity放到root/system/lib/目录下
- filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY);
- if(filehandle)
- {
- getStringFunc = (jstring (*)(JNIEnv *,jobject,jstring))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_getString");
- if(getStringFunc)
- {
- mun = getStringFunc(env, obj, name);
- }
- dlclose(filehandle);
- filehandle = NULL;
- }
- return mun
- }
4.编写Android.mk
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_LDLIBS := -llog
- LOCAL_C_INCLUDES += system/core/include/cutils
- LOCAL_SHARED_LIBRARIES := \
- libdl \
- libcutils
- LOCAL_PRELINK_MODULE := false
- LOCAL_MODULE := libsoHello
- LOCAL_MODULE_TAGS := optional
- LOCAL_SRC_FILES := so_hello_SoHelloActivity.cpp
- LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
- include $(BUILD_SHARED_LIBRARY)
使用mm命令编译so_hello_SoHelloActivity.cpp,便可以生成libsoHello.so库。
然后这个so库就可以用啦!
综述:
这里主要使用了dlopen、dlsym、dlclose三个函数来加载so库:
void *filehandle = NULL;
jint (*addFunc)(JNIEnv *,jobject,jint,jint) = NULL;
jint mun = 0
//事先把libNativeExampleActivity放到root/system/lib/目录下
filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY);
if(filehandle)
{
addFunc = (jint (*)(JNIEnv *,jobject,jint,jint))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_addFunction");
if(addFunc)
mun = addFunc(env, obj, a, b);
dlclose(filehandle);
filehandle = NULL;
}
http://blog.csdn.net/mirkerson/article/details/8642280
http://www.qtcn.org/bbs/read-htm-tid-61200.html
Android Java调用Qt写的so库的更多相关文章
- Qt打开外部程序和文件夹需要注意的细节(Qt调用VC写的动态库,VC需要用C的方式输出函数,否则MinGW32编译过程会报错)
下午写程序中遇到几个小细节,需要在这里记录一下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 QProcess *process = new QProcess(this ...
- java调用dll或so动态库文件(c++/c)
java调用dll或so动态库文件(c++/c) 博客分类: 工作 CC#C++JavaEclipse java调用dll或so动态库文件(c++/c)开发平台:Eclipse3.3.1.1+CD ...
- 【转载】java调用C++写的DLL
用java调用C++写的DLL一直以来都是一个比较麻烦但又很常见的问题. 我们知道,使用 JNI 调用 .dll/.so 共享类库是非常非常麻烦和痛苦的. 如果有一个现有的 .dll/.so 文件,如 ...
- c++ c# java 调用 c++ 写的dll
1. vs 中新建win32 dll 项目 testdll 添加实现文件 test.cpp #include "stdafx.h" #include <ios ...
- 在Android中调用C#写的WebService(附源代码)
由于项目中要使用Android调用C#写的WebService,于是便有了这篇文章.在学习的过程中,发现在C#中直接调用WebService方便得多,直接添加一个引用,便可以直接使用将WebServi ...
- Android 如何调用自写APK和非自写APK
由于项目需要,调用一个现成的APK,总结之余,顺便把怎么调用自写APK的方法也写上,以做比较 1.如何调用现成的APK: 先上调用代码,然后再一一解释: Intent mIntent = new In ...
- 通过COM组件方式实现java调用C#写的DLL文件
转自这里 最近一段时间单位在做一个Web项目,工程师用JAVA语言,需要公用人员信息,统一用户名和密码,原有的平台中是用C#语言开发的,在网上查找解决方法,通过JAVA调用C#的DLL文件实现.网上资 ...
- 通过COM组件方式实现java调用C#写的DLL文件 转
最近一段时间单位在做一个Web项目,工程师用JAVA语言,需要公用人员信息,统一用户名和密码,原有的平台中是用C#语言开发的,在网上查找解决方法,通过JAVA调用C#的DLL文件实现.网上资料很多,自 ...
- 实现通过COM组件方式实现java调用C#写的DLL文件的完整demo
最近因为工作需要,客户那边工程师使用的是JAVA语言开发的程序,我们这边平台中是用C#语言开发的,因为有些操作必须统一,所以我在网上查找解决方法,自己也实践过,在这里做个笔记吧,分享一下. 声明:下面 ...
随机推荐
- SpringBoot项目优化和Jvm调优(楼主亲测,真实有效)
项目调优 作为一名工程师,项目调优这事,是必须得熟练掌握的事情. 在SpringBoot项目中,调优主要通过配置文件和配置JVM的参数的方式进行. 在这边有一篇比较好的文章,推荐给大家! Spring ...
- JAVA SE回顾及思考(2)——数组的复制与动态扩展
我们知道在Java中数组是非基本类型既数组是对象(Object)的子类,所以用下面的这种方式是不能复制该对象的 public static void main(String[] args) { int ...
- CentOS下Apache的停止和卸载
昨晚搞到一台全球性价比最高的服务器,折腾一晚上,好不容易把node服务开启了,结果访问不了我的网站!!! 访问我的网站,显示的是一个Apache欢迎页面.我想,是不是像之前那样,80端口没有开放,然后 ...
- matlab 图像分块及恢复
1. block_divide % 返回的块向量构成的矩阵,其维度信息为 K^2 * N,每一列由块构成的列向量 function P = block_divide(I, K) r = size(I, ...
- database disk image is malformed解决方法
作者:朱金灿 来源:http://blog.csdn.net/clever101 在Hudson上终止一次Job的运行之后,Hudson在服务器上更新源码出现下图的错误: 查了下英文意思,大意是svn ...
- 微信上传素材 {"errcode":41005,"errmsg":"media data missing"} 解决方法和思路
哎lol 连跪两把 就来写写博客 今天遇到一个问题 ,微信公众号开发上传素材是提示报错 41005 errcode":41005,"errmsg":&q ...
- SQL server添加链接服务器脚本
---恢复内容开始--- exec sp_addlinkedserver 'ZZSJK','','SQLOLEDB','192.168.10.22' --链接服务器名称 ‘’ ip地址exec s ...
- Matlab使用鼠标标注图像位置并返回坐标(标注图像ROI)
代码 function ROI=LabelBox(filename) Mat=imread(filename); imshow(Mat); mouse=imrect; pos=getPosition( ...
- python 整数中1出现的次数
把整数转换为字符串 用count计数 # -*- coding:utf- -*- class Solution: def NumberOf1Between1AndN_Solution(self, n) ...
- CCD 与 CMOS
窗帘快门与全局快门: 窗帘快门,每次只允许一条缝的光线摄入,因此会呈现自上而下的扫描式拍摄,也就意味着画面上的不同高度,其实拍摄的时间是不同的,也就进一步造成了在高速移动的火车上,如果拍摄窗外的景物, ...