当前位置:首页 » 编程软件 » 共享库编译extemc

共享库编译extemc

发布时间: 2022-09-18 16:53:52

Ⅰ Android 怎么自定义共享库

源码根目录下有个 vendor (供应商) 目录,专门用于存放各个供应商的会有代码。其中有一个个 sample 目录,这是 Google 用于示范如何编写自定义共享库的示例,它展示了自定义共享库、JNI 调用、对库的使用方法及皮肤定制等功能。下面我们通过对该示例进行分析,让大家熟悉这个轻量级的框架。


1、首先看一下 sample 目录的结构:

sample
├── Android.mk
├── apps
│ ├── Android.mk
│ ├── client
│ └── upgrade
├── frameworks
│ ├── Android.mk
│ └── PlatformLibrary
├── MODULE_LICENSE_APACHE2
├── procts
│ ├── AndroidProcts.mk
│ └── sample_addon.mk
├── README.txt
├── sdk_addon
│ ├── hardware.ini
│ └── manifest.ini
└── skins
└── WVGAMedDpi

Android.mk: 该文件用于编写构建规则,默认继承 Android 的 make 框架。
frameworks: 该目录在这里的意义等同于 Android 源码中的 frameworks 。
PlatformLibrary: 该目录就自定义共享库。

apps: 该目录用于编写依赖该库的应用程序。经过测试也可以用来编写不依赖该库的程序,这有个好处,让开发商可以把自己特有的应用集成到框架中。
client 与 upgrade: 这是两个依赖该库的应用程序示例。
procts: 该目录中的文件对包含该库与 Android 框架集成的信息,如模块名称等。
AndroidProcts.mk: 指明该模块的 make 配置文件的在哪里。
sample_addon.mk :模块的配置信息。

sdk_addon: 该目录对该库的硬件需求进行定义。
hardware.ini: 定义模块对硬件的需求。
manifest.ini: 模块的说明文件。名称、供应商等。
skins: 该目录用于存放自定义皮肤。
WVGAMedDpi: 已经定义好的一套皮肤。

2.如何封装 java 共享库?

PlatformLibrary 为我们展示了封装 Java 共享库的方法。其目录结构如下: frameworks/PlatformLibrary
├── Android.mk
├── com.example.android.platform_library.xml
├── java
│ └── com
│ └── example
│ └── android
│ └── platform_library
│ └── PlatformLibrary.java
└── README.txt

Android.mk: 该文件说明如何构建该模块。
com.example.android.platform_library.xml: 该文件是模块注册时需要的文件。该文件需要被放置到 /system/etc/permissions 目录下。
Java /*: Java 源码所在目录。具体步骤:

a、编写 Java 库,并将源码放到 java 目录下。这一步和编写普通 Java 程序没有差别。
b、编写 Android.mk,内容如下:

# 获得当前目录,清空环境变量
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) # 源码所在目录,all-subdir-java-files 表示所有了目录中的 Java 文件。
LOCAL_SRC_FILES := \
$(call all-subdir-java-files) # 该模块是可选的。
LOCAL_MODULE_TAGS := optional # Java 模块名称
LOCAL_MODULE:= com.example.android.platform_library # 编译为 Java 库。最近以 jar 的形式而不是 apk 的形式存在。
include $(BUILD_JAVA_LIBRARY) # 构建该库的 API 文档
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files)
LOCAL_MODULE:= platform_library

# 文档对应的库
LOCAL_DROIDDOC_OPTIONS := com.example.android.platform_library

# 库的类型
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_DROIDDOC_USE_STANDARD_DOCLET := true # 编译为 Java API。
include $(BUILD_DROIDDOC)

c、编写 com.example.android.platform_library.xml,内容如下:
< xml version="1.0" encoding="utf-8" >
<permissions>
<!-- 库的名称及对应的 Jar 文件位置 -->
<library name="com.example.android.platform_library"
file="/system/framework/com.example.android.platform_library.jar"/>
</permissions> 现在基本的库我们已经编写完成,现在需要对框架中的其它文件进行配置。
d、编写 sample/frameworks/Android.mk, 内容如下:

# 包含子目录中的所有 make 文件 include $(call all-subdir-makefiles) 该文件与 sample/Android.mk 文件相同。
e、编写 sample/sdk_addon/manifest.ini,内容如下: # 该模块的名称、供应商及描述
name=Sample Add-On
vendor=Android Open Source Project
description=sample add-on # 构建该模块的 Android 平台代号
api=3 # 模块的版本号。必须为整数。
revision=1 # 该模块中包括的共享库列表
libraries=com.example.android.platform_library # 对每个库的详细定义,格式如下:
# <library.name>=<name>.jar;<desc> # <library.name>: 通过前面 libraies 定义的库的名称。
# <name>.jar: 包含库 API 的 jar 文件。该文件放在 libs/add-on 下面。
com.example.android.platform_library=platform_library.jar;Sample optional plaform library 该文件还可包括该模块的其它定义,如皮肤等,为了保持该文档清晰易懂的初衷,这里不做介绍,需要了解可以给我邮件。
f、编写 sample/procts/sample_addom.mk,内容如下:

# 要植入系统镜像的应用及可选类库。可以包括 Java 库和本地库。这里我们只有 Java 库。
PRODUCT_PACKAGES := \ com.example.android.platform_library # 把 xml 文件复制到系统镜像中相应的位置去。
PRODUCT_COPY_FILES := \ vendor/
sample/frameworks/PlatformLibrary/com.example.android.platform_library.xml:system/etc/permissions/
com.example.android.platform_library.xml # 这个扩展的名称
PRODUCT_SDK_ADDON_NAME := platform_library # 把模块的 manifest 和硬件配置文件复制到系统镜像中相应的位置。 PRODUCT_SDK_ADDON_COPY_FILES := \
vendor/sample/sdk_addon/manifest.ini:manifest.ini \
vendor/sample/sdk_addon/hardware.ini:hardware.in # 把库的 Jar 包复制到相应的位置。 PRODUCT_SDK_ADDON_COPY_MODULES := \
com.example.android.platform_library:libs/platform_library.jar # 文档的名称。必须与。
# LOCAL_MODULE:= platform_library
PRODUCT_SDK_ADDON_DOC_MODULE := platform_library # 这个扩展继承系统扩展。 $(call inherit-proct, $(SRC_TARGET_DIR)/proct/sdk.mk) # 这个扩展的真实名字。这个名字会用于编译。
# 用 'make PRODUCT-<PRODUCT_NAME>-sdk_addon' 的形式来编译此扩展。
PRODUCT_NAME := sample_addon

g、编写 sample/procts/AndroidProcts.mk,内容如下:
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/sample_addon.mk h、最后运行make -j8 PRODUCT-sample_addon-sdk_addon,编译扩展。
至此,我们就完成了 Java 库的封装。

3、接下来我们再来看如何通过 JNI 的方式对 C 代码进行封装。

a、在 sample/frameworks/PlatformLibrary 目录下添加一个文件夹,用于放置 JNI 本地代码,目录结构如下:

frameworks/PlatformLibrary/jni
├── Android.mk
└── PlatformLibrary.cpp

b、把 frameworks/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java
文件改写为 JIN 调用接口,代码如下 : package com.example.android.platform_library; import android.util.Config;
import android.util.Log; public final class PlatformLibrary {
static { / Load the library. If it's already loaded, this does nothing. System.loadLibrary("platform_library_jni");
private int mJniInt = -1; public PlatformLibrary() {} / Test native methods. public int getInt(boolean bad) {
// this alters mJniInt //
int result = getJniInt(bad); // reverse a string, for no very good reason //
String reverse = reverseString("Android!"); Log.i("PlatformLibrary", "getInt: " + result + ", '" + reverse + "'"); return mJniInt; //
/ Simple method, called from native code. private static void yodel(String msg) {
Log.d("PlatformLibrary", "yodel: " + msg); //
/ Trivial native method call. If "bad" is true, this will throw an
/ exception. native private int getJniInt(boolean bad); / Native method that returns a new string that is the reverse of
/ the original. This also calls yodel(). native private static String reverseString(String str);
}

c、在 frameworks/PlatformLibrary/jni/PlatformLibrary.cpp 中编写 PlatformLibrary.java 中规定本地调用的具体实现。
d、编写 frameworks/PlatformLibrary/jni/Android.mk,内容如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional # JNI 模块的名称
LOCAL_MODULE:= libplatform_library_jni # 依赖的源代码文件
LOCAL_SRC_FILES:= \
PlatformLibrary.cpp # 编译时需要的库
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libnativehelper \
libcutils \
libutils # 没有静态库
LOCAL_STATIC_LIBRARIES := # 包含必须的 JNI 头文件
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) # 编译器选项
LOCAL_CFLAGS += # 对该模块不进行预编译。使用预编译可以提高模块的性能。
LOCAL_PRELINK_MODULE := false # 把它编译成动态共享库
include $(BUILD_SHARED_LIBRARY) 该文件主要定义了本地库的名字、依赖、编译选项及编译方式。
e、修改 frameworks/PlatformLibrary/Android.mk,在末尾添加如下两行:

include $(CLEAR_VARS) # 调用子目录中的 make 文件。
include $(call all-makefiles-under,$(LOCAL_PATH))

f、修改 sdk_addon/sample_addon.mk,在PRODUCT_PACKAGES 中添加该 JNI 本地库。

PRODUCT_PACKAGES := \
com.example.android.platform_library \
libplatform_library_jni

g、编译即可。至此,添加 JNI 库完毕。

4、添加接下来我们再看看如何添加原生应用程序

添加原生应用程序就很简单了,只需要把按照 Android 应用开发的基本方法,写好一个应用,该应用可以依赖这个扩展,也可以不依赖。如 sample 中的 client 应用,目录结构如下: apps/client/
├── AndroidManifest.xml
├── Android.mk
└── src
└── com
└── example
└── android
└── platform_library
└── client
└── Client.java

a、在应用根目录中添加一个 Android.mk 文件,内容如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE_TAGS := user # 目标名称
LOCAL_PACKAGE_NAME := PlatformLibraryClient # 只编译这个apk包中的java文件
LOCAL_SRC_FILES := $(call all-java-files-under, src) # 使用当前版本的 SDK

LOCAL_SDK_VERSION := current # 依赖使用刚才编写的扩展
LOCAL_JAVA_LIBRARIES := com.example.android.platform_library include $(BUILD_PACKAGE)

b、在 AndroidManifest.xml 中添加一句:
<uses-library android:name="com.example.android.platform_library" />

c、修改 sdk_addon/sample_addon.mk,在PRODUCT_PACKAGES 中添加该 JNI 本地库。

PRODUCT_PACKAGES := \
com.example.android.platform_library \
libplatform_library_jni \
PlatformLibraryClient

d、编译即可。至此,添加 JNI 库完毕。

5、其他功能如添加皮肤等,这里就不一一示范了,请参考<sdk-src>/vendor/sample。

Ⅱ 关于使用QLibrary如何读取共享库

现在程序讲究个模块化,插件化,所有共享库的读取变的尤其关键,把程序写成各种各样的共享库,那升级的时候只需要重写下某个库,在保证头文件不变的情况下,更新上去,就能完美运行。Qt中读取使用共享库的类叫QLibrary. 使用起来也相当简单,最基本的使用只需要知道4个函数,load(), isLoad(), revovle()和unload().在绝大部分情况下,下面这四个函数就足够完成工作了。下面是个小例子:
// 库名是mylib.so,这个文件后缀可以不加
// Qt会根据操作系统自动添加后缀
QLibrary lib(mylib);
// 这是最重要的地方,根据你要调用的库函数先定义一个相同的函数指针
typedef (MyType *)(InstanceOf)();
// instanceOf是你要读取的库中的函数名字
InstanceOf instance = (InstanceOf)lib.revolve(instanceOf);
// revolve成功则运行函数
// 不成功则输出错误字符串
if(instance)
MyType *ret = instance();elseqDebug() << lib.errorString();
这里并没有使用到load()函数,这是因为revolve()函数会自动去加载库,同时Qt还给出了一个简单的static函数来读取库中的函数:
typedef (MyType *)(InstanceOf)();
InstanceOf instance = QLibrary::revolve(mylib,instanceOf);
if(instance)
MyType *ret = instance();
最后要着重说明的就是,QLibrary只能读取共享库内的C函数,这是因为C++为了达到面向对象编程封装,继承,多态等特性,实际的symbol table和你定义的是不同的,他会在编译过程中加入一些字符,比如上例中的instanceOf函数,在symbol table中可能是_ZV12instanceOf4FR这样的存在,所以如果把该函数声明为简单的类函数,QLibrary是找不到的,必须要将你准备让QLibrary读的函数声明为C函数,如下
extern C MyType *instanceOf(){return new MyType();}这个函数返回MyType的一个对象,这样,只要你有相应的头文件,就可以完全使用这个对象内的其他类函数了。

Ⅲ Linux下的动态共享链接库的优点有哪些

动态共享库有以下的优点,使它在Linux开发中比静态链接库更加的流行。
(1) 节省内存
动态共享库无论被多少应用程序使用,在内存中都只存在一个动态共享库的副本,而不像静态链接库那样,一个应用程序在运行中用到静态链
接库,就会有多个静态链接库的副本 。
(2) 节省磁盘
这和节省内存有点相似,同样这也是由于静态链接库存在多个静态链接库的副本造成的。同样的应用程序,使用动态共享库编译出的版本通常比使用静态链接库编译出来的版本要小。因此,在嵌入式系统开发中使用动态共享库也不节省空间,提供了一种很好的选择。
(3) 便于软件修复与升级
由于动态共享是独立于应用程序存在的,因此,用新版本的动态共享库替旧版本的工作将变得非常容易。如果使用静态链接库的话,假设在一个静态库中发现了一个
ug,那么要修正这个
ug的话,就要重新编译所有使用这个静态库的应用程序,使用这个静态库的应用程序有很多的话,可以想象工作量是有多大。
(4) 提高性能
与采用静态链接库臃肿的应用程序相比,采用动态共享库的应用程序明显“苗条”得多,这样当操作系统加载应用程序时,是需要把应用程序
复制到内存中的,这样的“苗条”的动态链接库也就有了很大的优势,同时提高了程序的性能。
当然,动态链接库在有上述这些优势的同时,也有以下的几个劣势。复杂性,兼容性,调试困难。但是它在Linux上使用频率上仍然比静态链接库要高的多。应用的更加广泛。

Ⅳ Android中静态库和共享库的区别

简单来讲:
静态库是在连接阶段直接拷贝到代码中使用的,而共享库是由加载器加载到内存,在运行时使用的。
编译出来的静态库(这里指jar包)里每个java文件对应的class文件都单独存在,可以直接导入Eclipse等IDE使用
而编译出来的共享库(jar包),内部是Android字节码Dex格式的文件,一般无法导入Eclipse等IDE使用。Android.mk中由BUILD_JAVA_LIBRARY指定生成共享BUILD_STATIC_JAVA_LIBRARY指定生成静态库。

Ⅳ android.mk ubuntu怎么编译

一个Android.mk file用来向编译系统描述你的源代码。具体来说:该文件是GNU Makefile的一小部分,会被编译系统解析一次或多次。你可以在每一个Android.mk file中定义一个或多个模块。每个模块属下列类型之一:
1)APK程序,一般的Android程序,编译打包生成apk文件
2)Java库,java类库,编译打包生成jar文件
3) CC++应用程序,可执行的CC++应用程序
4)CC++静态库,编译生成CC++静态库,并打包成.a文件
5)CC++共享库,编译生成共享库(动态链接库),并打包成.so, 有且只有共享库才能被安装/复制到您的应用软件(APK)包中。
(1)先看一个简单的例子:一个简单的"hello world",比如下面的文件:
sources/helloworld/helloworld.c
sources/helloworld/Android.mk
相应的Android.mk文件会像下面这样:

---------- cut here ------------------

普通的.mk一样

=====================================m、mm、mmm编译命令===========================================

android源码目录下的build/envsetup.sh文件,描述编译的命令
- m: Makes from the top of the tree.
- mm: Builds all of the moles in the current directory.
- mmm: Builds all of the moles in the supplied directories.

所以要想使用这些命令,首先需要在android源码根目录执行build/envsetup.sh 脚本设置环境。
m:编译所有的模块
mm:编译当前目录下的模块,当前目录下要有Android.mk文件
mmm:编译指定路径下的模块,指定路径下要有Android.mk文件

下面举个例子说明,假设我要编译android下的hardwarelibhardware_legacypower模块,当前目录为源码根目录,方法如下:
1、. build/envsetup.sh
2、mmm hardware/libhardware_legacy/power/
或者 :
1、. build/envsetup.sh
2、cd hardware/libhardware_legacy/power/
3、mm

m没有试过。默认上述两个编译命令,只编译发生变化的文件。如果要编译模块的所有文件,需要-b选项,例如mm -b或者mmm -b

make命令,也可以用来编译。如果是include $(BUILD_PACKAGE),用makeLOCAL_PACKAGE_NAME值;如果是include $(BUILD_EXECUTABLE)或者include $(BUILD_JAVA_LIBRARY),用makeLOCAL_MODULE值(未验证)。

Ⅵ 程序开发中库的作用

所谓库就是“程序库”,包含了一些通用函数的数据和二进制可执行机器码的文件。这些文件是目标文件的一种,其不能单独执行。但是如果将其与其他的可执行程序结合起来就可以执行了。这些目标文件通常可以完成同一类功能,它们可以作为其他执行程序的一部分来执行。由于库的存在,使得用户编写的程序模块化更强,从而可以加快程序的再编译,提高代码的复用性,同时也使程序更加易于升级和管理。对于读取文件内容,将大写字母转换为小写字母的简单程序来说,其程序的构成可以分为两个相对独立的模块,一个模块负责从外部设备上读入文件,一个模块负责将文件内容进行适当的转换。这两个模块分工明确,互相不需要了解对方的细节。当需要将程序升级为将小写字母转换为大写字母时,不需要改变第一个读入文件的模块,只需更新负责转换操作的模块就可以了。使用一个将小写字母转换为大写字母替换原来的转换处理模块,这时程序就完成了更新。假设现在需要生成一个读入文件内容,将文件中的多个空格合并为一个空格的程序时,就用不着重新生成一个文件读入模块,而直接使用第一个程序的文件读入模块就可以了。从链接方式上区分,程序库可分静态库和动态库(共享库)两种:
静态库:是在可执行程序运行前就已经加入到执行码中,成为执行程序的一部分来执行的。
共享库:是在执行程序启动时加载到执行程序中,可以被多个执行程序共享使用。

Ⅶ 如何在C++中使用共享库的动态加载

一、先看看测试程序
1.库部分
hello.h
[cpp] view plain
在CODE上查看代码片派生到我的代码片
#ifndef ANDROID_Hello_H
#define ANDROID_Hello_H
class Hello_Base
{
public:
virtual ~Hello_Base() {};
virtual int setctl(int ctl) = 0;
virtual int getctl(int ctl) = 0;
};
class Hello : public virtual Hello_Base
{
public:
virtual ~Hello() {};
static Hello* Instance();
int setctl(int ctl);
int getctl(int ctl);
private:
static Hello* _instance;
int myctl;
};
extern "C" Hello_Base* CreatHello();
typedef Hello_Base* CreatHelloClass();
#endif
hello.cpp
[cpp] view plain
在CODE上查看代码片派生到我的代码片
#include "hello.h"
#include <stdio.h>
extern "C" Hello_Base* CreatHello(){
return Hello::Instance();
}
Hello* Hello::_instance = 0;
Hello* Hello::Instance()
{
printf("TK------>>>>>>Hello::Instance---------\n");
if(_instance == 0){
_instance = new Hello();
}
return _instance;
}
int Hello::setctl(int ctl)
{
printf("TK------->>>>>>setctl-----\n");
this->myctl = ctl;
return 1;
}
int Hello::getctl(int ctl)
{
printf("TK------->>>>>>getctl-----\n");
return this->myctl;
}
编译成动态链接库,一般要求PIC位置无关:
g++ -shared -fPIC -o libhello.so hello.cpp
生成:libhello.so
2.测试用例
test.cpp
[cpp] view plain
在CODE上查看代码片派生到我的代码片
#include "so/hello.h"
#include <stdio.h>
#include <dlfcn.h>
int main()
{
void* hello = dlopen("/home/lianxi/c++/ku/so/libhello.so", RTLD_LAZY);
if(!hello){
printf("dlopen /home/lianxi/c++/ku/so/libhello.so error!\n");
return -1;
}
dlerror();
CreatHelloClass* Creat_Hello = (CreatHelloClass*)dlsym(hello,"CreatHello");
const char* dlsym_error = dlerror();
if (dlsym_error) {
printf("error %s\n",dlsym_error);
return -1;
}
Hello_Base* mHello = Creat_Hello();
mHello->setctl(5);
int result = mHello->getctl(0);
printf("TK------>>>>>result is %d\n",result);
dlclose(hello);
return 1;
}
编译:g++ -o test test.cpp -L. -ldl
执行./test结果:
[plain] view plain
在CODE上查看代码片派生到我的代码片
TK------>>>>>>Hello::Instance---------
TK------->>>>>>setctl-----
TK------->>>>>>getctl-----
TK------>>>>>result is 5
二、分析
1.libdl库为C语言开发,当需要在C++中dlsym某个符号时、需要声明库中该符号为extern “C”,比如例子中的extern "C" Hello_Base* CreatHello();
2.由于不可能像C语言那样将C++类中的那么多方法都dlsym出来,这里使用了C++中对于纯虚类的实例化是运行时链接的特点;也就是说要在C++中对于类使用共享库的动态链接、必须定义一个纯虚的子类。

Ⅷ Android 怎么自定义共享库

LOCAL_PATH := $(call my-dir)//标准mk语句,指编译路径,所有mk文件第一句都是这个 /**这个模块表示引用了一个本地的静态库 include $(CLEAR_VARS) //清除各种变量,因为这些变量是静态全局的,如果清除,下次编译时又会用到这些变量造成出错 LOCAL_MODULE := libopencore-amrnb //本地静态库模块的名字,这个名字在下面编译jni时需要引用 LOCAL_SRC_FILES := lib/libopencore-amrnb/smfwuxiao/article/details/6591927 NDK r5 开始支持预编译共享库。预编译共享库就是从其他地方获得源码编译出的共享库,而不是Android系统自带的。方法如下: 1、声明共享库模块 把共享库声明为一个独立模块。假如 libfoo.so 与 Android.mk 位于同一目录。则 Android.mk 应该这样写: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt # 模块名 LOCAL_SRC_FILES := libfoo.so # 模块的文件路径(相对于 LOCAL_PATH) include $(PREBUILT_SHARED_LIBRARY) # 注意这里不是 BUILD_SHARED_LIBRARY 这个共享库将被拷贝到 $PROJECT/obj/local 和 $PROJECT/libs/<abi> (strip过的) 2、在其他模块中引用这个共享库 在 Android.mk 中,将这个共享库的模块名加入 LOCAL_STATIC_LIBRARIES (静态库)或 LOCAL_SHARED_LIBRARIES (动态库) 例如, 使用 libfoo.so 的方法: include $(CLEAR_VARS) LOCAL_MODULE := foo-user LOCAL_SRC_FILES := foo-user.c LOCAL_SHARED_LIBRARY := foo-prebuilt include $(BUILD_SHARED_LIBRARY) 3、为共享库导出头文件 这个共享库一般有相应的头文件,比如 libfoo.so 就有 foo.h。 一个简单方法(在Android.mk中写): include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt LOCAL_SRC_FILES := libfoo.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY) 这样,使用该共享库的模块就会在它的 LOCAL_C_INCLUDES 变量加入该头文件搜索路径。 4、调试共享库 建议你的共享库保留调试信息。 $PROJECT/libs/<abi> 目录下的共享库都是 strip 之后的(没有调试信息)。有调试信息的版本可被ndk-gdb使用。 5、共享库 ABI 你的共享库与目标系统ABI的兼容性很重要。 请检查 TARGET_ARCH_ABI,有以下值: armeabi => ARMv5TE 以上 armeabi-v7a => ARMv7 以上 x86 => x86 建议: armeabi ABI 可以运行在所有 ARM CPU 上。

热点内容
androidapk文件夹 发布:2025-04-14 16:47:12 浏览:945
手机我的世界pvp服务器地址 发布:2025-04-14 16:45:42 浏览:579
脚本是什么意思lol 发布:2025-04-14 16:35:31 浏览:477
我的世界永恒七区服务器地址 发布:2025-04-14 16:27:41 浏览:61
2022雷凌又升级了哪些配置 发布:2025-04-14 16:27:00 浏览:695
gps平台源码 发布:2025-04-14 16:18:18 浏览:190
编译原理文法简化 发布:2025-04-14 16:17:45 浏览:179
如何理解残疾辅助器具配置机构 发布:2025-04-14 16:13:36 浏览:75
唱吧不够60秒怎么上传 发布:2025-04-14 16:11:16 浏览:959
淘宝登陆无法访问 发布:2025-04-14 16:10:20 浏览:300