win10下ndk编译arm可执行体

编译参考文章

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环境中构建。
工程结构图如下:
project.structure

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
原文地址:https://www.cnblogs.com/xunbu7/p/6974207.html