编译本地C ++共享对象与Android NDK [英] Compile native C++ shared object with Android NDK

查看:316
本文介绍了编译本地C ++共享对象与Android NDK的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经产生了的.so 通过C ++文件上莱纳斯并获得的.so 现在文件生成我有交叉编译该的.so 文件 ARM的Andr​​oid ,所以我必须通过来comiple它的Andr​​oid NDK ,使新genrated 的.so
可在我的Andr​​oid项目中使用。

因此​​,谁能帮助我,我不得不把生成的Linux的.so文件在我的Andr​​oid项目以及如何make文件(Android.mk)添加,以便它可以生成新的的.so 在我的$ p $现有方法的文件pvious Linux的生成的.so 文件。

我希望我的问题是清楚你的一切,如果不是请告诉我。

请帮助我。在此先感谢


解决方案

下面是建立一个本地C ++共享对象的步骤。


  1. 要你的项目加入原生支持。见Android的添加原生支持

  2. 您的C ++文件添加到文件夹JNI

  3. 创建一个 Android.mk ,把它添加到了JNI文件夹,并添加要支持的架构。例如:

      APP_ABI:= armeabi 86 MIPS armeabi,V7A


<醇开始=4>
  • 选择一个C ++运行时库。请参见NDK的CPLUSPLUS.README。我拿起STL端口的运行时(GNU的运行时间是有毒的,由于其许可证)。


  • 创建一个 Appication.mk ,把它添加到了JNI的文件夹,并添加魔力。例如:

      LOCAL_PATH:= $(叫我-DIR)#NDK_DEBUG_IMPORTS:= 1################################################## #######
    #库的STLport
    包括$(CLEAR_VARS)STLPORT_INCL:= /选择/ Android的NDK-R9 /来源/ CXX-STL / STLport的/的STLport
    STLPORT_LIB:= /选择/ Android的NDK-R9 /来源/ CXX-STL / STLport的/库/ $(TARGET_ARCH_ABI)LOCAL_MODULE:= stlport_shared
    LOCAL_SRC_FILES:= $(STLPORT_LIB)/libstlport_shared.soLOCAL_EXPORT_CPPFLAGS:=
    LOCAL_EXPORT_C_INCLUDES:= $(STLPORT_INCL)包括$(preBUILT_SHARED_LIBRARY)LOCAL_SHARED_LIBRARIES:= stlport_shared################################################## #######
    #加密++库
    包括$(CLEAR_VARS)CRYPTOPP_INCL:=的/ usr /本地/ cryptopp / Android的 - $(TARGET_ARCH_ABI)/包括:
    CRYPTOPP_LIB:=的/ usr /本地/ cryptopp / Android的 - $(TARGET_ARCH_ABI)/ lib目录LOCAL_MODULE:= cryptopp
    LOCAL_SRC_FILES:= $(CRYPTOPP_LIB)/libcryptopp.soLOCAL_EXPORT_CPPFLAGS:= -Wno-未使用的参数-Wno未使用的变量-Wno-未使用的功能
    LOCAL_EXPORT_C_INCLUDES:= $(CRYPTOPP_INCL)$(CRYPTOPP_INCL)/ cryptopp包括$(preBUILT_SHARED_LIBRARY)LOCAL_SHARED_LIBRARIES:= cryptopp################################################## #######
    #PRNG库
    包括$(CLEAR_VARS)APP_STL:= stlport_shared
    APP_MODULES:= PRNG stlport_shared cryptopp#我的屁股...... LOCAL_EXPORT_C_INCLUDES是没用的
    LOCAL_C_INCLUDES:= $(STLPORT_INCL)$(CRYPTOPP_INCL)LOCAL_CPP_FEATURES:= RTTI例外LOCAL_CPP_FLAGS:= -Wno-未使用的参数-Wno未使用的变量-Wno-未使用的功能
    LOCAL_CPP_FLAGS + =轮候册, - 排除,库,ALLLOCAL_LDLIBS:= -llog -landroid
    LOCAL_SHARED_LIBRARIES:= cryptopp stlport_sharedLOCAL_MODULE:= PRNG
    LOCAL_SRC_FILES:= libprng.cpp包括$(BUILD_SHARED_LIBRARY)


  • 我的图书馆取决于STLport的。下面的东西的的STLport库的保证我的图书馆被编译针对 stlport_shared.so stlport_shared.so 复制到APK。

    我的图书馆还取决于一个加密+ 的交叉编译版本。加密+还编译/对 stlport_shared.so 链接。下面的东西的的Crypto ++库的保证我的图书馆被编译针对 libcryptopp.so libcryptopp.so 复制到APK。

    最后,我的图书馆被称为出来。我的藏书以下的PRNG库的(它的一个文件测试项目)的东西。它建立 libprng.so ,并确保 libprng.so 复制到APK。

    您还需要Android的类。下面是我的样子。

     包com.cryptopp.prng;公共类PRNG {    静态{
            的System.loadLibrary(stlport_shared);
            的System.loadLibrary(cryptopp);
            的System.loadLibrary(PRNG);
        }    私有静态本地INT CryptoPP_Reseed(字节[]字节);    私有静态本地INT CryptoPP_GetBytes(字节[]字节);    私有静态对象锁=新的对象();    //类方法。返回从种子消耗的字节数。
        公共静态INT重新设定种子(字节[]种子){
            同步(锁){
                返回CryptoPP_Reseed(种子);
            }
        }    //类方法。返回生成的字节数。
        公共静态INT GetBytes会(字节[]字节){
            同步(锁){
                返回CryptoPP_GetBytes(字节);
            }
        }    //实例方法。返回从种子消耗的字节数。
        公众诠释补种(字节[]种子){
            同步(锁){
                返回CryptoPP_Reseed(种子);
            }
        }    //实例方法。返回生成的字节数。
        公众诠释的getBytes(字节[]字节){
            同步(锁){
                返回CryptoPP_GetBytes(字节);
            }
        }
    }

    Android的修改构建系统真的很烂。它从标准的制定为基础的项目十分不同和不良记录。但是,这就是Android提供了,所以这是你必须使用的东西。 Eclipse的Andr​​oid原生支持,围绕它建立。


    如果感兴趣的话,这里就是包装头文件的样子。您可以使用 JAVAH 从您的DEX文件生成它(编译Java类)。

      / * DO NOT EDIT这个文件 - 它是生成的机器* /
    #包括LT&;&jni.h GT;
    / *头类com_cryptopp_prng_PRNG * /的#ifndef _Included_com_cryptopp_prng_PRNG
    #定义_Included_com_cryptopp_prng_PRNG
    #IFDEF __cplusplus
    为externC{
    #万一
    / *
     *类别:com_cryptopp_prng_PRNG
     *方法:CryptoPP_Reseed
     *签名:([B)我
     * /
    JNIEXPORT jint JNICALL Java_com_cryptopp_prng_PRNG_CryptoPP_1Reseed
      (JNIEnv的*,JCLASS,jbyteArray);/ *
     *类别:com_cryptopp_prng_PRNG
     *方法:CryptoPP_GetBytes
     *签名:([B)我
     * /
    JNIEXPORT jint JNICALL Java_com_cryptopp_prng_PRNG_CryptoPP_1GetBytes
      (JNIEnv的*,JCLASS,jbyteArray);#IFDEF __cplusplus
    }
    #万一
    #万一

    I have generated a .so file via C++ on Linus and got .so file generated now I have cross compile this .so file for Android ARM so I have to comiple it via Android NDK so that new genrated .so can be used in my android project .

    So can anyone help me where I have to put Linux generated .so file in my Android project and what to add in Make file(Android.mk) so that it can generate new .so file with existing methods in my previous Linux generated .so file.

    I hope my question is clear to you all, if not please tell me.

    Please help me. Thanks in advance

    解决方案

    Here are the steps to build a native C++ shared object.

    1. Add native support to your project. See Android's Add native support
    2. Add your C++ files to the JNI folder
    3. Create an Android.mk, add it to the the JNI folder, and add the architectures you want to support. For example:

      APP_ABI   := armeabi x86 mips armeabi-v7a
      

    1. Pick a C++ runtime library. See the CPLUSPLUS.README in the NDK. I picked STL Port for the runtime (the GNU runtime was toxic due to its license).

    2. Create an Appication.mk, add it to the the JNI folder, and add the magic. For example:

      LOCAL_PATH := $(call my-dir)
      
      # NDK_DEBUG_IMPORTS := 1
      
      #########################################################
      # STLport library
      include $(CLEAR_VARS)
      
      STLPORT_INCL     := /opt/android-ndk-r9/sources/cxx-stl/stlport/stlport
      STLPORT_LIB      := /opt/android-ndk-r9/sources/cxx-stl/stlport/libs/$(TARGET_ARCH_ABI)
      
      LOCAL_MODULE := stlport_shared
      LOCAL_SRC_FILES := $(STLPORT_LIB)/libstlport_shared.so
      
      LOCAL_EXPORT_CPPFLAGS :=
      LOCAL_EXPORT_C_INCLUDES := $(STLPORT_INCL)
      
      include $(PREBUILT_SHARED_LIBRARY)
      
      LOCAL_SHARED_LIBRARIES  := stlport_shared
      
      #########################################################
      # Crypto++ library
      include $(CLEAR_VARS)
      
      CRYPTOPP_INCL   := /usr/local/cryptopp/android-$(TARGET_ARCH_ABI)/include
      CRYPTOPP_LIB    := /usr/local/cryptopp/android-$(TARGET_ARCH_ABI)/lib
      
      LOCAL_MODULE       := cryptopp
      LOCAL_SRC_FILES    := $(CRYPTOPP_LIB)/libcryptopp.so
      
      LOCAL_EXPORT_CPPFLAGS := -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function
      LOCAL_EXPORT_C_INCLUDES := $(CRYPTOPP_INCL) $(CRYPTOPP_INCL)/cryptopp
      
      include $(PREBUILT_SHARED_LIBRARY)
      
      LOCAL_SHARED_LIBRARIES  := cryptopp
      
      #########################################################
      # PRNG library
      include $(CLEAR_VARS)
      
      APP_STL         := stlport_shared
      APP_MODULES     := prng stlport_shared cryptopp
      
      # My ass... LOCAL_EXPORT_C_INCLUDES is useless
      LOCAL_C_INCLUDES   := $(STLPORT_INCL) $(CRYPTOPP_INCL)
      
      LOCAL_CPP_FEATURES := rtti exceptions
      
      LOCAL_CPP_FLAGS    := -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function
      LOCAL_CPP_FLAGS    += -Wl,--exclude-libs,ALL
      
      LOCAL_LDLIBS            := -llog -landroid
      LOCAL_SHARED_LIBRARIES  := cryptopp stlport_shared
      
      LOCAL_MODULE    := prng
      LOCAL_SRC_FILES := libprng.cpp
      
      include $(BUILD_SHARED_LIBRARY)
      

    My library depends on STLport. The stuff following "STLport library" ensures my library is compiled against stlport_shared.so, and the stlport_shared.so is copied into the APK.

    My library also depends upon a cross-compiled version of Crypto++. Crypto++ was also compiled/linked against stlport_shared.so. The stuff following "Crypto++ library" ensures my library is compiled against libcryptopp.so, and the libcryptopp.so is copied into the APK.

    Finally, my library is called out. My library is the stuff following "PRNG library" (its a one file test project). It builds libprng.so, and ensures libprng.so is copied into the APK.

    You'll also need Android classes. Here's what mine looks like.

    package com.cryptopp.prng;
    
    public class PRNG {
    
        static {
            System.loadLibrary("stlport_shared");
            System.loadLibrary("cryptopp");
            System.loadLibrary("prng");
        }
    
        private static native int CryptoPP_Reseed(byte[] bytes);
    
        private static native int CryptoPP_GetBytes(byte[] bytes);
    
        private static Object lock = new Object();
    
        // Class method. Returns the number of bytes consumed from the seed.
        public static int Reseed(byte[] seed) {         
            synchronized (lock) {
                return CryptoPP_Reseed(seed);
            }
        }
    
        // Class method. Returns the number of bytes generated.
        public static int GetBytes(byte[] bytes) {
            synchronized (lock) {
                return CryptoPP_GetBytes(bytes);
            }
        }
    
        // Instance method. Returns the number of bytes consumed from the seed.
        public int reseed(byte[] seed) {
            synchronized (lock) {
                return CryptoPP_Reseed(seed);
            }
        }
    
        // Instance method. Returns the number of bytes generated.
        public int getBytes(byte[] bytes) {
            synchronized (lock) {
                return CryptoPP_GetBytes(bytes);
            }
        }
    }
    

    The Android modified build system really sucks. Its sufficiently different from standard make-based projects and poorly documented. But that's what Android offers, so that's what you have to use. Eclipse's Android native support is built around it.


    If interested, here's what the wrapper header file looks like. You can use javah to generate it from your DEX file (compiled Java classes).

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_cryptopp_prng_PRNG */
    
    #ifndef _Included_com_cryptopp_prng_PRNG
    #define _Included_com_cryptopp_prng_PRNG
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_cryptopp_prng_PRNG
     * Method:    CryptoPP_Reseed
     * Signature: ([B)I
     */
    JNIEXPORT jint JNICALL Java_com_cryptopp_prng_PRNG_CryptoPP_1Reseed
      (JNIEnv *, jclass, jbyteArray);
    
    /*
     * Class:     com_cryptopp_prng_PRNG
     * Method:    CryptoPP_GetBytes
     * Signature: ([B)I
     */
    JNIEXPORT jint JNICALL Java_com_cryptopp_prng_PRNG_CryptoPP_1GetBytes
      (JNIEnv *, jclass, jbyteArray);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    这篇关于编译本地C ++共享对象与Android NDK的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆