android_c++ 高级编程NDK学习笔记四

Bioniccc++进行原生应用开发所提供的posix标准c

1回顾标准库

Java平台的标准库是javaclasslibrary(JCL)

C语言的标准库为libc

2gnuc(glibc)embeddedlinuxc(uclibc)bionic

Bionic提供以下功能:

内存管理

文件输入输出

字符串操作

数学

日期与时间

进程控制

信号处理

网络套接字

多线程

用户和组

系统配置

命名服务切换

AndroidNDK提供了缺失功能的完整列表,可以从头文件中获得这些信息

ANDROID_NDK_HOME/platforms/android-<api-level>/arch-<architecture>/usr/include

3内存管理

三种内存分配方式

静态分配:静态或全局变量

自动分配:函数参数和局部变量

动态分配:内存的大小和范围的分配取决于运行时因素

C语言的动态内存管理---------------------------------------------------------------

动态分配内存:

Void*malloc(size_tsize);//是以字节为单位来分配内存的

释放动态内存:

Void*free(void*memory);//通过之前指向动态内存的指针来释放内存

改变动态内存分配

Void*fealloc(void*memory,size_tsize);//重新分配内存

C++的动态内存管理-----------------------------------------------------------------

动态分配内存:

示例代码如下:

//单个元素的动态内存分配

Int*myInt=newint;

If(NULL==myInt){

//不能分配足够的内存

}else{

//使用分配的内存

*myInt=0;

}

//多个元素的动态内存分配

Int*myIntArray=newint[16];

Int*myIntArray=newint;

If(NULL==myInt){

//不能分配足够的内存

}else{

//使用分配的内存

myIntArray[8]=8;

}

释放动态内存:

//释放单个元素的动态内存

DeletemyInt;

myInt=0;

//释放多个元素的动态内存

Delete[]myIntArray;

myIntArray=0;

改变动态内存

使用适当的标准模板库(standardtemplatelibrarySTL)

4标准I/O

可以通过c库提供的satndardfileI/o(stdio)函数与文件系统进行交互

C库提供了两种文件i/o:

低级I/O:原始的i/o函数

I/o:可缓冲的I/O函数,适合处理数据流

标准流#include<stdio.h>

Stdin:标准输入

Stdout:标准输出

Stderr:标准错误

打开流----------------------------------------------------------------------------

FILE*fopen(constchar*filename,//文件名

constchar*opentype);//控制文件打开方式

R只读

W只写

A以符加方式打开文件,不存在则新建

R+在读写模式下打开文件

W+在读写模式下打开文件,载断后文件长度为0

A+打开文件进行读取和符加

示例代码如下:

#include<stdio.h>

FILE*stream=fopen("/data/data/com.example.hellojni/test.txt","w");

if(NULL==stream){

MY_LOG_VERBOSE("cannotopen!");

}else{

//使用流

//关闭流

}

写入流-----------------------------------------------------------------------------------------------

//向流中写入数据块

size_tfwrite(constvoid*data,size_tsize,size_tcount,FILE*stream);

示例代码如下:

//使用fwrite向流中写入数据块

chardata[]={'h','e','l','l','o','\n'};

size_tcount=sizeof(data); //数据块长度

//向流中写入数据

if(count!=fwrite(data,sizeof(char),count,stream)){

MY_LOG_VERBOSE("fwriteerror!");

}else{

MY_LOG_VERBOSE("fwritesuccess!");

}

向流中写入字符序列

Intfputs(constchar*data,FILE*stream);

//向流中写入字符串序列

if(EOF==fput("hello\n",stream)){

MY_LOG_VERBOSE("fputerror!");

}else{

MY_LOG_VERBOSE("fputsuccess!");

}

向流中写入单个字符

Intfputc(intc,FILE*stream);

//向流中写入单个字符

charc='c';

if(c!=fputc(c,stream)){

MY_LOG_VERBOSE("fputcerror!");

}else{

MY_LOG_VERBOSE("fputcsuccess!");

}

//向流中写入有格式的字符串

Intfprintf(FILE*stream,constchar*format,...);

//向流中写入有格式的数据

if(0>fprintf(stream,"the%sis%d","number",2)){

MY_LOG_VERBOSE("fprintferror!");

}else{

MY_LOG_VERBOSE("fprintfsuccess!");

}

刷新缓冲区

Intfflush(FILE*stream);

流的读取--------------------------------------------------------------------------------------

从流中读取数据块

Size_tfread(void*data,size_tsize,size_tcount,FILE*stream);

//从流中读取四个字符的块数据

charbuffer[5];

size_ttmpSize=4;

if(tmpSize!=fread(buffer,sizeof(char),tmpSize,stream)){

MY_LOG_VERBOSE("freaderror!");

}else{

//以空结尾

buffer[4]=NULL;

//输出缓冲区到日志文件

MY_LOG_INFO("read:%s",buffer);

}

从流中读取字符序列

Char*fgets(char*buffer,intcount,FILE*stream);

//从流中读取字符串序列

charsBuffer[1024];

if(NULL==fgets(buffer,1024,stream)){

MY_LOG_VERBOSE("fgetserror!");

}else{

MY_LOG_INFO("fgetsread:%s",buffer);

}

从流中读取单个字符

Intfgetc(FILE*stream);

//从流中读取单个字符

unsignedcharch;

intresult;

result=fgetc(stream);

if(EOF==result){

MY_LOG_VERBOSE("fgetcerror!");

}else{

ch=(unsignedchar)result;

MY_LOG_INFO("fgetcread:%s",ch);

}

从流中读取格式数据

Intfscanf(FILE*stream,constchar*format,...);

//从流中读取格式字符串

chars[5];

inti;

if(2!=fscanf(stream,"the%sis%d",s,&i)){

MY_LOG_VERBOSE("fscanferror!");

}

检查文件结尾

Intfeof(FILE*stream);

//检查文件结尾

charcheckBuffer[1024];

while(0==feof(stream)){

fgets(buffer,1024,stream);

MY_LOG_INFO("fgetsread:%s",checkBuffer);

}

搜索位置------------------------------------------------------------

Intfseek(FILE*stream,//流指针

longoffset,//相对偏移量

intwhence);//位置参数

位置参数类型:

SEEK_SET:偏移量相对于流的开头

SEEK_CUR:偏移量相对于当前位置

SEEK_END:偏移量相对于流结尾

示例代码如下:

fputs("abcd",stream);

//倒回四个流字节

fseek(stream,-4,stream);

//用efgh重写abcd

fputs("efgh",stream);

错误检查----------------------------------------------------------------------------------

Intferror(FILE*stream);

//检查错误

if(0!=ferror(stream)){

//前一次请求中产生错误

}

关闭流--------------------------------------------------------------------------------------

Intfclose(FILE*stream);

//关闭流

if(0!=fclose(stream)){

MY_LOG_VERBOSE("fcloseerror!");

}

5与进程交互

执行shell命令(可以用systemshell传递命令)

#include<stdlib.h>

//用系统函数执行shell命令

intsysResult;

//在应用程序中新建目录

sysResult=system("mkdir/data/data/com.example.hellojni/temp");

if(-1==sysResult||127==sysResult){

MY_LOG_VERBOSE("shelloptionfailed!");

}

与子进程通信

FILE*popen(constchar*command,constchar*type);

//用ls打开一个通道并打印输出

FILE*tmpStream;

tmpStream=popen("ls","r");

if(NULL==stream){

MY_LOG_ERROR("unabletoexecutethecommand!");

}else{

charbuffer[1024];

intstatus;

//从命令行读取每一行

while(NULL!=fgets(buffer,1024,stream)){

MY_LOG_INFO("read:%s",buffer);

}

//关闭通道并获取其状态

status=pclose(stream);

MY_LOG_INFO("processexitedwithstatus%d",status);

}

6系统配置

Android的系统属性是以键值对的方式保存,bionic提供了一组函数来查询

需要包含的头文件

#include<sys/system_properties.h>

属性名最大值PROP_NAME_MAX

属性值最大值PROP_VALUE_MAX

通过名称获取系统属性值

Int__system_property_get(constchar*name,char*value);

//通过名称获取系统属性值

charparamValue[PROP_VALUE_MAX];

if(0==__system_property_get("ro.product.model",paramValue)){

MY_LOG_INFO("systempropertiescannotfindoritisnull!");

}else{

MY_LOG_INFO("productmodel:%s",paramValue);

}

通过名称获取系统属性值

Constprop_info*__system_property_find(constchar*name);

//通过名移获取系统属性

constprop_info*property;

property=__system_property_find("ro.product.model");

if(NULL==property){

MY_LOG_INFO("systempropertycannotfind!");

}else{

charname[PROP_NAME_MAX];

charvalue[PROP_VALUE_MAX];

//取得系统属性名称和值

if(0==__system_property_read(property,name,value)){

MY_LOG_INFO("%sisempty",name);

}else{

MY_LOG_INFO("%sis%s",name,value);

}

}

用户和组

需要头文件:

#include<unistd.h>

获取应用程序用户组

//使用getuid获得应用程序的用户id

uid_tuid;

uid=getuid();

MY_LOG_INFO("applicationuseridis%u",uid);

//使用getgid获得应用程序组id

gid_tgid;

gid=getgid();

MY_LOG_INFO("applicationgroupidis%u",gid);

获取应用程序用户名

//获取应用程序用户名

char*username;

username=getlogin();

MY_LOG_INFO("Applicationusernameis%s",username);

8进程间通信

Bionic暂不支持进程间通信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值