编译参考文章
http://blog.csdn.net/john_1984/article/details/12622215
一、编写soLoader主文件
soLoader.c内容:
#include <stdio.h> typedef int (*MAIN_FN)(int,char**); int main(int argc,char* argv[]){ printf("hello so! "); int ret = dlopen("/data/local/xxx.so"); if (ret==0) { printf("file not found! "); } void* pfn = dlsym(ret,"main"); if (pfn==NULL) { printf("method "main" not found! "); } ((MAIN_FN)pfn)(argc,argv); printf("result: %x ",ret); }
二、编译o文件
E:DocumentsAndroidsdk dk-bundle oolchainsarm-linux-androideabi-4.9prebuiltwindows-x86_64in>arm-linux-androideabi-gcc.exe --sysroot=E:DocumentsAndroidsdk dk-bundleplatformsandroid-19arch-arm -o E:VMShareWorkAndriodantidebugsoLoaderjnisoLoader.o -c E:VMShareWorkAndriodantidebugsoLoaderjnisoLoader.c
三、链接o文件为elf文件
E:DocumentsAndroidsdk dk-bundle oolchainsarm-linux-androideabi-4.9prebuiltwindows-x86_64in>arm-linux-androideabi-gcc.exe --sysroot=E:DocumentsAndroidsdk dk-bundleplatformsandroid-19arch-arm -o E:VMShareWorkAndriodantidebugsoLoaderjnisoLoader E:VMShareWorkAndriodantidebugsoLoaderjnisoLoader.o
或者直接编译链接(二,三命令合并):
E:DocumentsAndroidsdk dk-bundle oolchainsarm-linux-androideabi-4.9prebuiltwindows-x86_64in>arm-linux-androideabi-gcc.exe --sysroot=E:DocumentsAndroidsdk dk-bundleplatformsandroid-19arch-arm -o E:VMShareWorkAndriodantidebugsoLoaderjnisoLoader E:VMShareWorkAndriodantidebugsoLoaderjnisoLoader.c
四、push到手机,执行
//pc端命令
E:VMShareWorkAndriodantidebugsoLoaderjni>adb push soLoader /data/local/tmp
//adb shell shell@hammerhead:/data/local/tmp # chmod 775 soLoader shell@hammerhead:/data/local/tmp # ./soLoader hello so! file not found! method "main" not found! [1] + Stopped (signal) ./soLoader shell@hammerhead:/data/local/tmp # ls
===========第二种简单的利用Android.mk文件自动生成elf(eclipse的ndk自动插件)============
也可在Eclipse下创建android工程,Android Tools -> Add Native Support...,利用配置好的ndk环境编译链接生成elf文件。
参考文章
http://sodino.com/2015/01/12/dlopen-usage-demo/
为了方便编译生成so及binary,仍然在Eclipse+CDT+NDK环境中构建。
工程结构图如下:
comparison.c将编译生成待加载的动态链接库libComparison.so,其代码如下:
1
2
3
4
5
6
7
8
|
#ifndef _Comparison_c
#define _Comparison_c
int max (int a, int b) {
return a > b? a : b;
}
#endif
|
Execute.c将编译生成可在Android中直接运行的可执行文件。其代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#include<stdio.h>
#include<dlfcn.h>
int main(void) {
// 必须写明绝对路径,否则找不着so文件呢
void *handle = dlopen("/data/local/libComparison.so",RTLD_LAZY);
int(*pfun)(int,int);
const char *error = NULL;
if(handle==NULL)
{
printf("error:dlopen libComparison.so Fail.
");
return 1;
}
dlerror();
pfun = dlsym(handle,"max");
if((error=dlerror()) != NULL)
{
printf("error:dlsym method max fail.
");
return 1;
}
printf("input tow number:
");
int a, b;
scanf("%d%d", &a, &b);
int result = (*pfun)(a, b);
printf("Get:%d and %d, the max() return:%d
",a, b, result);
dlclose(handle);
return 0;
}
|
Android.mk的作用在于声明配置并分别生成libComparison.so及Execute(binary)。其代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Execute
LOCAL_SRC_FILES := Execute.c
#生成独立的可执行文件
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE := Comparison
LOCAL_SRC_FILES := comparison.c
#普通的so库
include $(BUILD_SHARED_LIBRARY)
|
右击工程 -> Build Project。则在libs下生成了libComparison.so及Execute(binary)。
使用ADB命令将这两个文件push到手机。并执行操作查看效果如下图:
==========第三种简单的利用Android.mk文件自动生成elf(eclipse手动添加jni环境)==========
手动添加好jni文件夹,配置好Android.mk和Application.mk后,手动切换ndk-build.cmd到工程的jni目录,编译执行(手动添加ndkbuilder的本质)
PS E:DocumentsworkspaceCydiaModuleSojni> E:DocumentsAndroidsdk dk-bundle dk-build.cmd Android NDK: WARNING: APP_PLATFORM android-19 is higher than android:minSdkVersion 17 in E:/Documents/workspace/CydiaModuleSo/AndroidManifest.xml. NDK binaries will *not* be comptible with devices older than android-19. See https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md for more information. Android NDK: WARNING:E:/Documents/workspace/CydiaModuleSo/jni/Android.mk:test.cy: non-system libraries in linker flags: -lsubstrate-dvm -lsubstrate Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the Android NDK: current module [armeabi-v7a] Prebuilt : libsubstrate.so <= jni/ [armeabi-v7a] Install : libsubstrate.so => libs/armeabi-v7a/libsubstrate.so [armeabi-v7a] Prebuilt : libsubstrate-dvm.so <= jni/ [armeabi-v7a] Install : libsubstrate-dvm.so => libs/armeabi-v7a/libsubstrate-dvm.so [armeabi-v7a] Compile++ arm : test.cy <= test.cpp In file included from E:/Documents/workspace/CydiaModuleSo/jni/test.cpp:2: E:/Documents/workspace/CydiaModuleSo/jni/substrate.h:315:52: warning: variadic templates are a C++11 extension [-Wc++11-extensions] template <typename Type_, typename Kind_, typename ...Args_> ^ E:/Documents/workspace/CydiaModuleSo/jni/test.cpp:31:29: warning: format specifies type 'unsigned int' but the argument has type 'void *' [-Wformat] LOGD("dvm image: 0x%08X", (void* )image); ~~~~ ^~~~~~~~~~~~~ E:/Documents/workspace/CydiaModuleSo/jni/test.cpp:12:63: note: expanded from macro 'LOGD' #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) ^~~~~~~~~~~ 2 warnings generated. [armeabi-v7a] StaticLibrary : libstdc++.a [armeabi-v7a] SharedLibrary : libtest.cy.so [armeabi-v7a] Install : libtest.cy.so => libs/armeabi-v7a/libtest.cy.so