• Run c++ program with boost on Android


    http://nick.luckygarden.org/

    Android 很早就支持 NDK, 官方教程上说你可以把 native 代码编译成一个 .so, 在 java 代码中通过 jni 调用这个 .so.

    现在在做一个 C++ 跨平台的库. 需要支持 Android. 为了在 Android 上测试, 自然可以按照教程里写 java, jni. 但其实也可以抛开 java. 直接将 c++ 代码编译成可执行文件. 下面将整个过程记录下来, 备忘, 也希望能帮助用这样的需求的人.

    先下载 sdk, ndk. 解压缩就好, 然后设置好环境变量 ANDROID_SDKROOT, NDKROOT 指向这两个目录. 并将 $NDKROOT, $ANDROID_SDKROOT/platform-tools, $ANDROID_SDKROOT/tools 加入 PATH. 下面的操作使用的环境是 NDK r8, OS X 10.8.
    开始啦:

    #include <stdio.h>
    int main(){printf("hello world. ");return 0;}

    把这个文件保存为 /tmp/hello.cpp. 要编译这个程序, 需要写一个 Android.mk


    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS) # mk 文件前面两句都这样, 不解释

    LOCAL_MODULE := hello-world # 模块名, 必须唯一
    LOCAL_SRC_FILES := ../hello.cpp # 要编译的源文件
    include $(BUILD_EXECUTABLE) # 编译成可执行文件. 这个是关键.
    # 其他的选项是 BUILD_SHARED_LIBRARY, BUILD_STATIC_LIBRARY 编译成 .so, .a

    貌似还只能把这个 .mk 文件放到一个 jni 的文件夹里. 然后在 /tmp 目录执行 ndk-build. 如果环境都设置好了, 这个能够编译成功. 放到模拟器上试试吧.
    执行

    android - avd

    打开 Android Virtual Device Manager (注意 – avd 之间有一个空格), 创建一个虚拟机, 然后启动它. 确保一切 ok. 然后执行


    adb push libs/armeabi/hello-world /data/ && adb shell /data/hello-world
    1372 KB/s (299852 bytes in 0.213s)
    hello world.

    push 到模拟器, 然后执行 hello-world.

    继续. 修改一下代码, 试试 c++ 的库文件.


    #include <iostream>
    int main(){std::cout<<"hello world"; return 0;}

    用 ndk-build 编译会发现有错误. 因为没有 stl 的支持.

    nickx:/tmp $ ndk-build
    Compile++ thumb : hello-world <= hello.cpp
    jni/../hello.cpp:1:20: error: iostream: No such file or directory
    jni/../hello.cpp: In function 'int main()':
    jni/../hello.cpp:4: error: 'cout' is not a member of 'std'
    make: *** [obj/local/armeabi/objs/hello-world/__/hello.o] Error 1

    在 /tmp/jni 下建立 Application.mk, 加上下面一句:

    APP_STL := gnustl_static # 另一个选项是 gnustl_shared

    链接 gnustl. 再编译就 ok 了.
    因为项目要链接 boost, 加上 boost header 试试吧.

    #include <iostream>
    #include <boost/thread.hpp>
    void proc(){std::cout << "hello world ";}
    int main()
    {
    boost::thread thrd(proc);
    thrd.join();
    return 0;
    }

    首先是找不到 boost 头文件. 这里要做一些准备工作. 将需要编译的 boost 库在 android 编译好. 这里就不赘述了. 得到 libboost_thread.a, libboost_system.a, 将这些文件这样组织

    /vendor
      /boost
        Android.mk
        /boost
          thread.hpp
          ..
        /lib
          libboost_thread.a
          libboost_system.a
    

    其中的 Android.mk 的内容是这样的:


    LOCAL_PATH:= $(call my-dir)

    include $(CLEAR_VARS)
    LOCAL_MODULE:= boost_thread
    LOCAL_SRC_FILES:= lib/android/lib$(LOCAL_MODULE).a
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) # 导出头文件, 因为有这句, 在我们的程序中的 Android.mk 文件中就不需要 LOCAL_C_INCLUDES 来指定 boost 头文件所在位置了.
    include $(PREBUILT_STATIC_LIBRARY) # 所谓的编译好的静态库

    include $(CLEAR_VARS)
    LOCAL_MODULE:= boost_system
    LOCAL_SRC_FILES:= lib/android/lib$(LOCAL_MODULE).a
    LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)

    boost 库就准备好了. 现在修改程序的 Android.mk 文件:

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)

    LOCAL_MODULE := hello-world
    LOCAL_SRC_FILES := ../hello.cpp
    LOCAL_CPP_FEATURES := exceptions rtti # boost thread 库需要 exceptions 的支持. rtti 后面也会用到
    LOCAL_STATIC_LIBRARIES := boost_thread boost_system # 要的就是这两个库.
    include $(BUILD_EXECUTABLE)

    $(call import-module,boost) # 导入 boost 库.

    再次编译会提示 import-module 找不到 boost, 需要定义 NDK_MODULE_PATH

    nickx:/tmp $ export NDK_MODULE_PATH=/vendor
    nickx:/tmp $ ndk-build
    Compile++ thumb : hello-world <= hello.cpp
    Prebuilt : libboost_thread.a <= /vendor/boost/lib/android/
    Prebuilt : libboost_system.a <= /vendor/boost/lib/android/
    Executable : hello-world
    Install : hello-world => libs/armeabi/hello-world

    到这里差不多了.
    文中提到的 .mk 文件中的宏 (LOCAL_..) 的具体含义参见 $NDKROOT/documentation.html

  • 相关阅读:
    PlayerPrefs存储Vector3等结构数据
    Kafka集群部署及測试
    火云开发课堂
    Thinking in Java:容器深入研究
    求int型数据在内存中存储时1的个数
    JAVA 几种多线程的简单实例 Thread Runnable
    Android利用Intent与其它应用交互
    kernel
    Azure DocumentDB 正式发布
    在公有云平台体验开源方案的自动部署
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318644.html
Copyright © 2020-2023  润新知