Bionic C
Google 创建一个新的 C 库而不复用现有的 GNU C 库(glibc)或 Embedded Linux C 库(uClibc)的动机可总结为以下三点:
1、许可:glibc 和 uClibc 在 GNU Lesser General Public License(LGPL, GNU 宽通用公共许可)下均可用,从而限制了可被专用应用程序使用的方式。相反,Bionic 是在 BSD 许可下发布的,该许可非常自由,不对库的使用作任何限制。
2、速度:Bionic 是专门为移动计算精心设计的,针对移动设备上有限的 CPU 周期和可用内存进行了裁剪以提高效率。
3、大小:Bionic 的核心理念是简单化。它提供了针对内核功能的轻量级包装器和一组较小的 API,使得它比其他的代替品小。
4、兼容性:Bionic 不以任何方式与其他 C 库二进制兼容,用其他 C 库生成的目标文件和静态库不应该与 Bionic 进行动态链接,这样做通常会导致无法链接或无法正确执行你的原生应用程序。除此之外,任何与其他 C 库静态链接生成的、且不与 Bionic 混合的应用程序都可以在在 Android 平台上运行,除非它在运行时动态加载了其他系统库。
Bionic 提供 C 标准库宏、类型定义、函数和少数 Android 特有的特性,这些特性可分项在以下功能域中列出:
1、内存管理
1 /* 包含标准 C 库头文件 */ 2 #include <stdlib.h> 3 4 /* 分配 16 个元素的整形数组 */ 5 int* dynamicIntArray = (int*)malloc(sizeof(int) * 16); 6 7 if( NULL = dynamicIntArray){ 8 /* 不能分配足够的内存,返回为 NULL */ 9 10 }else{ 11 /* 通过整形指针使用内存 */ 12 *dynamicIntArray = 0; 13 dynamicIntArray[8] = 8; 14 15 /* 重新分配已分配的动态内存 */ 16 int* newDynamicIntArray = (int*)realloc(dynamicIntArray, sizeof(int) * 32); 17 18 /* 释放分配的内存 */ 19 free(dynamicIntArray); 20 dynamicIntArray = NULL; 21 } 22 23 /* C++ 代码中单个元素的动态内存分配 */ 24 int* dynamicInt = new int; 25 26 /* C++ 代码中多个元素的动态内存分配 */ 27 int* dynamicIntArray = new int[16]; 28 29 if( NULL = dynamicIntArray){ 30 /* 不能分配足够的内存,返回为 NULL */ 31 32 }else{ 33 /* 使用已分配的内存 */ 34 dynamicIntArray[8] = 8; 35 36 /* 释放单个元素的动态内存 */ 37 delete dynamicInt; 38 dynamicInt = 0; 39 40 /* 释放数组动态内存 */ 41 delete[] dynamicIntArray; 42 dynamicIntArray = 0; 43 }
2、文件输入输出
1 /* 包含标准 I/O 库头文件 */ 2 #include <stdio.h> 3 4 /* 以只写模式打开一个流 */ 5 FILE* stream = fopen("/data/data/com.example.hellojni/test.txt", "w"); 6 if( NULL = stream ) 7 { 8 /* 写文件打不开 */ 9 }else{ 10 /* 使用流 */ 11 char data[] = {'h', 'e', 'l', 'l', 'o', '\n'}; 12 size_t count = sizeof(data) / sizeof(data[0]); 13 14 /* 向流中写入数据块 */ 15 if( count != fwrite(data, sizeof(chart), count, stream) ) 16 { 17 /* 向流中写数据时产生错误 */ 18 } 19 20 /* 向流中写入字符序列 */ 21 if( EOF == fputs("hello\n", stream) ) 22 { 23 /* 向流中写数据时产生错误 */ 24 } 25 26 /* 向流中写入单个字符 */ 27 char c = 'c'; 28 if( c != fputs(c, stream) ) 29 { 30 /* 向字符串中写字符时产生错误 */ 31 } 32 33 /* 写带格式的数据 */ 34 if( 0 > fprintf(stream, "The %s is %d.", "number", 2 )) 35 { 36 /* 写带格式的数据时产生错误 */ 37 } 38 39 /* 刷新输出缓冲区 */ 40 if( EOF == fflush(stream)) 41 { 42 /* 清空缓冲区时产生错误 */ 43 } 44 45 char buffer[5]; 46 size_t count = 4; 47 48 /* 从流中读取 4 个字符 */ 49 if( count != fread(buffer, sizeof(chart), count, stream)) 50 { 51 /* occurred 从流中读数据时产生错误 */ 52 }else{ 53 /* 以空结尾 */ 54 buffer[4] = NULL; 55 56 /* 输出缓冲区 */ 57 MY_LOG_INFO("read: %s", buffer); 58 } 59 60 char buffer[1024]; 61 62 /* 从流中读取换行符结尾的字符序列 */ 63 if( NULL == fgets(buffer, 1024, stream)) 64 { 65 /* occurred 读取流时产生错误 */ 66 }else{ 67 MY_LOG_INFO("read: %s", buffer); 68 } 69 70 unsigned char ch; 71 int result; 72 73 /* 从流中读取单个字符 */ 74 result = fgetc(stream); 75 if( EOF == result) 76 { 77 /* occurred 从流中读取时产生错误 */ 78 }else{ 79 /* 获取实际字符 */ 80 ch = (unsigned char)result; 81 } 82 83 char s[5]; 84 int i; 85 86 /* 读带格式的数据 */ 87 fscanf(stream, "The %s is %d", s, &i); 88 89 char buffer[1024]; 90 /* 直到文件尾 */ 91 while( 0 = feof(stream)) 92 { 93 /* 读取并输出字符串 */ 94 fgets(buffer, 1024, stream); 95 MY_LOG_INFO("read: %s", buffer); 96 } 97 98 /* 写入流中 */ 99 fputs("abcd", stream); 100 101 /* 倒回 4 个字节*/ 102 fseek(stream, -4, SEEK_CUR); 103 104 /* 用 efgh 重写 abcd */ 105 fputs("efgh", stream); 106 107 /* 检查错误 */ 108 if( 0 != ferror(stream)) 109 { 110 /* 前一次请求中产生错误 */ 111 } 112 113 /* 关闭流 */ 114 if( 0 != fclose(stream)) 115 { 116 /* 关闭流时产生错误 */ 117 } 118 }
3、字符串管理
4、数学
5、日期和时间
6、进程管理
1 #include <stdlib.h> 2 3 int result; 4 5 /* 执行 shell 命令 */ 6 7 result = system("mkdir /data/data/com.example.hellojni/temp"); 8 if( -1 == result || 127 == result) 9 { 10 /* 执行 shell 命令失败 */ 11 } 12 13 #include <stdio.h> 14 FILE* stream 15 16 /* 向 ls 命令打开一个只读通道 */ 17 stream = popen("ls", "r"); 18 if( NULL == stream) 19 { 20 MY_LOG_ERROR("Unable to execute the command."); 21 }else{ 22 char buffer[1024]; 23 int status; 24 25 /* 从命令行输出中读取每一行*/ 26 while( NULL != fgets(buffer, 1024, stream)) 27 { 28 MY_LOG_INFO("read: %s", buffer); 29 } 30 31 /* 关闭通道并获取其状态 */ 32 status = pclose(stream); 33 MY_LOG_INFO("process existed with status &d", status); 34 }
7、信号处理
8、网络套接字
9、多线程
10、用户和组
1 #include <unistd.h> 2 3 /* 获取应用程序的用户 ID */ 4 uid_t uid; 5 uid = getuid(); 6 7 MY_LOG_INFO("Application User ID is %u", uid); 8 9 /* 获取应用程序的用户组 ID */ 10 gid_t gid; 11 gid = getgid(); 12 13 MY_LOG_INFO("Application Group ID is %u", gid); 14 15 /* 获取应用程序的用户名*/ 16 char* username; 17 username = getlogin(); 18 19 MY_LOG_INFO("Application User name is %s", username);
11、系统配置
1 #include <sys/system_properties.h> 2 3 char value[PROP_VALUE_MAX]; 4 5 /* 获取 product model 属性 */ 6 if( 0 == __system_property_get("ro.product.model", value)) 7 { 8 /* 系统属性未找到或值为空 */ 9 }else{ 10 MY_LOG_INFO("product model: %s", value); 11 } 12 13 const prop_info* property; 14 15 /* 获取 product model 系统属性 */ 16 property = __system_property_find("ro.product.model"); 17 if( NULL == property) 18 { 19 /* 系统属性未找到 */ 20 }else{ 21 char name[PROP_NAME_MAX]; 22 char value[PROP_VALUE_MAX]; 23 } 24 25 /* 获取系统属性名称和值 */ 26 if( 0 == __system_property_read(property, name, value)) 27 { 28 MY_LOG_INFO("%s is empty."); 29 }else{ 30 MY_LOG_INFO("%s: %s", name, value); 31 }
12、命名服务切换

浙公网安备 33010602011771号