以下是构建本机 C++ 共享对象的步骤。
- 为您的项目添加本机支持。请参阅 Android 的 Add native support
- 将 C++ 文件添加到 JNI 文件夹中
-
创建一个Android.mk,将其添加到 JNI 文件夹,然后添加您想要支持的架构。例如:
APP_ABI := armeabi x86 mips armeabi-v7a
选择一个 C++ 运行时库。请参阅 NDK 中的 CPLUSPLUS.README。我为运行时选择了 STL 端口(GNU 运行时由于其许可证而有毒)。
-
创建一个Appication.mk,将其添加到JNI 文件夹中,然后添加魔法。例如:
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)
我的库依赖于 STLport。 "STLport library" 后面的内容确保我的库是针对 stlport_shared.so 编译的,并且 stlport_shared.so 被复制到 APK 中。
我的库也依赖于cross-compiled version of Crypto++。 Crypto++ 也被编译/链接到stlport_shared.so。 "Crypto++ library" 后面的内容确保我的库是针对 libcryptopp.so 编译的,并且 libcryptopp.so 被复制到 APK 中。
最后,我的图书馆被调出。我的库是 "PRNG library" 之后的东西(它是一个文件测试项目)。它构建 libprng.so,并确保将 libprng.so 复制到 APK 中。
您还需要 Android 课程。这是我的样子。
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);
}
}
}
Android 修改后的构建系统真的很烂。它与标准的基于 make 的项目有很大的不同,并且文档记录很差。但这就是 Android 提供的,所以这就是你必须使用的。 Eclipse 的 Android 原生支持就是围绕它构建的。
如果有兴趣,这里是包装头文件的样子。您可以使用javah 从您的 DEX 文件(已编译的 Java 类)生成它。
/* 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