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 = 039 
40   /* 释放数组动态内存 */
41   delete[]  dynamicIntArray;
42   dynamicIntArray = 043 }

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、命名服务切换

 

posted @ 2015-07-05 09:32  壬子木  阅读(754)  评论(0)    收藏  举报