转载: Android原生(Native)C开发之一 环境搭建篇
2009年02月25日,星期三
Android是基于Linux的操作系统,处理器是ARM的,所以要在Linux或Windows等x86系统上编译Android能运行的程序,你需要一个交叉编译器。
在Linux下面,你可以自已编译一个交叉编译环境,但Windows下面,就比较复杂(也可以在cygwin中编译一个),但你可以选择下载一个现成的交叉编译环境:
http://www.codesourcery.com/gnu_toolchains/arm/download.html
Windows: http://www.codesourcery.com/gnu_toolchains/arm/portal/package3400/public/arm-none-linux-gnueabi/arm-2008q3-41-arm-none-linux-gnueabi.exe
Linux: http://www.codesourcery.com/gnu_toolchains/arm/portal/package3399/public/arm-none-linux-gnueabi/arm-2008q3-41-arm-none-linux-gnueabi.bin
安装好了之后,将 CodeSourcery编译器的bin目录 (我的是D:\Program Files\CodeSourcery\Sourcery G++ Lite\bin)加入你的PATH环境变量中,就可以开始你的Android Native C开发之旅了,写好一个简单的C程序:
#include
int main(int argc, char** argv) {
printf(”hello android!\nI’m %s!\nI like android very much!!!\n”, “Martin Foo”);
return 0;
}
另存成hello.c,进入命令行模式,确保交叉编译器的bin目录,及Android SDK的tools目录在你的系统环境变量的path里面,用如下命令编译:
arm-none-linux-gnueabi-gcc -static hello.c -o hello
注意,一定要加上static参数,否则编译好的可能会在Android上不能运行。
启动Android模拟器,用如下命令将文件push到Android模拟器上:
adb shell mkdir /dev/sample
adb push hello /dev/sample/hello
adb shell chmod 777 /dev/sample/hello
先创建 /dev/sample目录,再将编译好的hello上传上去,最后将hello改成可执行的。
再进入命令行模式,进入Android的shell环境:
adb shell
#cd /dev/sample
#./hello
进入 /dev/sample目录,执行hello,运行结果如下图:
标签:Android, lib
发布在 Gphone | 一条评论 »
转载: Android原生(Native)C开发之二 framebuffer篇
2009年02月25日,星期三
如对Android原生(Natvie)C开发还任何疑问,请参阅http://emck.avaw.com/?p=205
虽然现在能通过交叉环境编译程序,并push到Android上执行,但那只是console台程序,是不是有些单调呢?下面就要看如何通过Linux的 framebuffer 技术在Android上画图形,关于Linux的framebuffer技术,这里就不再详细讲解了,请大家google一下。
操作framebuffer的主要步骤如下:
1、打开一个可用的FrameBuffer设备;
2、通过mmap调用把显卡的物理内存空间映射到用户空间;
3、更改内存空间里的像素数据并显示;
4、退出时关闭framebuffer设备。
下面的这个例子简单地用framebuffer画了一个渐变的进度条,代码 framebuf.c 如下:
#include
#include
#include
#include
#include
inline static unsigned short int make16color(unsigned char r, unsigned char g, unsigned char b)
{
return (
(((r >> 3) & 31) << 11) |
(((g >> 2) & 63) << 5) |
((b >> 3) & 31) );
}
int main() {
int fbfd = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize = 0;
char *fbp = 0;
int x = 0, y = 0;
int guage_height = 20, step = 10;
long int location = 0;
// Open the file for reading and writing
fbfd = open(”/dev/graphics/fb0″, O_RDWR);
if (!fbfd) {
printf(”Error: cannot open framebuffer device.\n”);
exit(1);
}
printf(”The framebuffer device was opened successfully.\n”);
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf(”Error reading fixed information.\n”);
exit(2);
}
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf(”Error reading variable information.\n”);
exit(3);
}
printf(”sizeof(unsigned short) = %d\n”, sizeof(unsigned short));
printf(”%dx%d, %dbpp\n”, vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );
printf(”xoffset:%d, yoffset:%d, line_length: %d\n”, vinfo.xoffset, vinfo.yoffset, finfo.line_length );
// Figure out the size of the screen in bytes
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;;
// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);
if ((int)fbp == -1) {
printf(”Error: failed to map framebuffer device to memory.\n”);
exit(4);
}
printf(”The framebuffer device was mapped to memory successfully.\n”);
//set to black color first
memset(fbp, 0, screensize);
//draw rectangle
y = (vinfo.yres – guage_height) / 2 – 2; // Where we are going to put the pixel
for (x = step – 2; x < vinfo.xres – step + 2; x++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*((unsigned short int*)(fbp + location)) = 255;
}
y = (vinfo.yres + guage_height) / 2 + 2; // Where we are going to put the pixel
for (x = step – 2; x < vinfo.xres – step + 2; x++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*((unsigned short int*)(fbp + location)) = 255;
}
x = step – 2;
for (y = (vinfo.yres – guage_height) / 2 – 2; y < (vinfo.yres + guage_height) / 2 + 2; y++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*((unsigned short int*)(fbp + location)) = 255;
}
x = vinfo.xres – step + 2;
for (y = (vinfo.yres – guage_height) / 2 – 2; y < (vinfo.yres + guage_height) / 2 + 2; y++) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
*((unsigned short int*)(fbp + location)) = 255;
}
// Figure out where in memory to put the pixel
for ( x = step; x < vinfo.xres – step; x++ ) {
for ( y = (vinfo.yres – guage_height) / 2; y < (vinfo.yres + guage_height) / 2; y++ ) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
if ( vinfo.bits_per_pixel == 32 ) {
*(fbp + location) = 100; // Some blue
*(fbp + location + 1) = 15+(x-100)/2; // A little green
*(fbp + location + 2) = 200-(y-100)/5; // A lot of red
*(fbp + location + 3) = 0; // No transparency
} else { //assume 16bpp
unsigned char b = 255 * x / (vinfo.xres – step);
unsigned char g = 255; // (x – 100)/6 A little green
unsigned char r = 255; // A lot of red
unsigned short int t = make16color(r, g, b);
*((unsigned short int*)(fbp + location)) = t;
}
}
//printf(”x = %d, temp = %d\n”, x, temp);
//sleep to see it
usleep(200);
}
//clean framebuffer
munmap(fbp, screensize);
close(fbfd);
return 0;
}
注意,在Android环境,framebuffer设备不是象linux一样的 /dev/fb0,而是 /dev/graphics/fb0 ,
fbfd = open(”/dev/graphics/fb0″, O_RDWR);
打开framebuffer设备,
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);
将设备map到一块内存,然后就可以操作这块内存空间来显示你想画的图形了。
最后别忘了关闭设备:
munmap(fbp, screensize);
close(fbfd);
效果图如下:
标签:Android, framebuffer, lib
发布在 Gphone | 评论关闭
转载: Android原生(Native)C开发之三 鼠标事件篇(捕鼠记)
2009年02月25日,星期三
在做SDL至Android的移植时,键盘事件是能正常捕获到,看了SLD的源码,发现用的device是 /dev/tty0,但是鼠标叫是不能成功捕获,总是得到 0,运行命令查看devices时,显示如下:
# cat /proc/bus/input/devices cat /proc/bus/input/devices I: Bus=0000 Vendor=0000 Product=0000 Version=0000 N: Name=”qwerty” P: Phys= S: Sysfs=/class/input/input0 U: Uniq= H: Handlers=kbd mouse0 event0 B: EV=2f B: KEY=ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff f fffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe B: REL=3 B: ABS=7 B: SW=1 |
进入 /dev/input 目录,发现在3个device文件:mice,mouse0,event0,分别 cat这3个文件,发现只有 event0 有反应,如下图:
而且不管是点击鼠标还是按键,都有反应,但显示的是一堆乱码,而且点击鼠标出来的东西要多一点,难道这就是传说是的 touchscreen ?!
为了分析 event0 的返回值,写了一段代码 testmice.c,如下:
#include #include #include #include static int event0_fd = -1; struct input_event ev0[64]; //for handling event0, mouse/key/ts static int handle_event0() { int button = 0, realx = 0, realy = 0, i, rd; rd = read(event0_fd, ev0, sizeof(struct input_event) * 64); if ( rd < sizeof(struct input_event) ) return 0; for (i = 0; i < rd / sizeof(struct input_event); i++) { printf(”", ev0[i].type, ev0[i].code, ev0[i].value); if (ev0[i].type == 3 && ev0[i].code == 0) realx = ev0[i].value; else if (ev0[i].type == 3 && ev0[i].code == 1) realy = ev0[i].value; else if (ev0[i].type == 1) { if (ev0[i].code == 158) { //if key esc then exit return 0; } } else if (ev0[i].type == 0 && ev0[i].code == 0 && ev0[i].value == 0) { realx = 0, realy = 0; } printf(”event(%d): type: %d; code: %3d; value: %3d; realx: %3d; realy: %3d\n”, i, ev0[i].type, ev0[i].code, ev0[i].value, realx, realy); } return 1; } int main(void) { int done = 1; printf(”sizeof(struct input_event) = %d\n”, sizeof(struct input_event)); event0_fd = open(”/dev/input/event0″, O_RDWR); if ( event0_fd < 0 ) return -1; while ( done ) { printf(”begin handel_event0…\n”); done = handle_event0(); printf(”end handel_event0…\n”); } if ( event0_fd > 0 ) { close(event0_fd); event0_fd = -1; } return 0; } |
用交叉编译器编译好后(编译过程就不再详述,请参见 blog:Android原生(Native)C开发之一:环境搭建篇),push至 emulator后执行后,切换到android 模拟器,在模拟器上点几下mouse,程序就会打出你点击的信息,效果如下,果然能正确得到点击的 mouse pos,如下图:
分析上面的返回值,发现当按下 mouse left button 时,会得到4个事件,2个 type = 3 的事件返回了 pos x, pos y 的值,即mouse click pos, 另外1个 type = 1 的事件是按键事件(keydown),value就是按下的键的key,为0的应该就是 key的release事件,当松开 mouse时,也会得到两个 type = 1, 0 的事件,没有仔细去看它们的返回值,反正已经正确得到了 mosue的事件,下一步就是改SDL的事件驱动源码了…
参考链接: USB Mouse and Touch Screen ( TS ) Input(EN)[http://www.webkinesia.com/games/embedded.php]
标签:Android, event mouse, lib
发布在 Gphone | 评论关闭
转载: Android原生(Native)C开发之四 SDL移植笔记
2009年02月25日,星期三
SDL(Simple DirectMedia Layer)是一套开放源码的跨平台多媒体开发库,使用C语言写成。SDL提供了多种图像、声音、键盘等的实现,可配置性与移植性非常高,开发者可以开发出跨多个平台(Linux、Windows、Mac OS X、Symbian、Widnows Mobiel等嵌入式系统,当然也包括今天要移植的平台:Android)的应用,目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用。
目前,SDL的稳定版本是 1.2.13,1.3还在开发中,可以通过SVN得到最新的代码,本次移植以 1.2.13为准,没有测试 1.3版的源码。请从 SDL 的官方网站下载 1.2.13 的源码,文件名为:SDL-1.2.13.zip,并解压,将得到一个 SDL-1.2.13 目录。
在Native编译SDL之前,要先装 Code Sourcery公司的arm交叉编译器,如果是用Windows操作系统,则一定要装 Cygwin(一个在windows上模拟linux的软件),因为在编译时要用到一些 linux命令,具体的步骤请参见:Port SDL/TinySDGL to android with native C,或自已在网上搜一些资料。
因为SDL是用纯C写的一套类库,所以移植性非常好,官方支持的系统有:Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX, and QNX,非官方支持的有:AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS, and OS/2,而且网上也有人将SDL移植到很多其他嵌入式系统,甚至有人将SDL移植到 Moto A1200,如此强大的可移植性,其架构真是值得好好学习。
现在切入正题,如何为Android量身定做一个 SDL,下面就从视频,音频,输入事件,定时器(video,audio,events[key,mouse],timer),多线程等几个方面来分析:
1.首先讲视频方面,Android是一个定制的Linux操作系统,Linux显示要么用 X11,要么用framebuffer技术,很显然Android并没有集成 X11(也许Android的软件界面是基于X11的?!),那只有唯一的选择:framebuffer!
打开$SDL/src/video目录,可以发现SDL支持多达30多种的视频显示技术,其中包括我们想要的fbcon及directfb,directfb我没有做测试,也许显示效果会比linux自带的fbcon好,有兴趣的朋友可以试一下,成功了别忘了告诉我;
2.再来谈音频,记得一个广告词:没有声音,再好的戏也出不来!可见音频对多媒体应用的重要性。
这次用的是OSS的driver,但用的是dsp及dma的实现,但在打开Android指定的音频文件 /dev/eac 时有误,所以音频这一块只是能编译通过,不能正常运行,正在考虑用ALSA (Advanced Linux Sound Architecture) 替代;
关于OSS大家可以参看IBM的文章: OSS–跨平台的音频接口简介,写得比较详细。
3.输入事件(键盘,鼠标)中的键盘事件不需要任何更改,就能正常处理,用的设备文件是 /dev/tty0,
但鼠标事件却不能正常处理,加上DEBUG_MOUSE发现用的是PS2的鼠标,但其实Android用的不是PS2的鼠标,用的应该是触摸屏(TouchScreen)鼠标,设备文件是 /dev/input/event0,详情请参见本人的blog: Android原生(Native)C开发之三:鼠标事件篇(捕鼠记),经过改动后,基本能实现鼠标的处理;
4.定时器用的是unix的实现;
5.多线程用的是pthread的实现,unix系统都是用pthread来实现多线程的,在 ln demo时别忘了加 -lpthread;
6.加载动态库用的是unix 的 dl库,同样,在ln demo时别忘了加 -ldl。
SDL提供了一个最小化的Makefile:Makefile.minimal,所有的实现都是 dummy,就是一个空的实现,编译能通过,但运行时什么都不能做,根据上面的分析,将 Makefile.minimal 的内容改成如下:
# Makefile to build the SDL library INCLUDE = -I./include CFLAGS = -g -s -O2 $(INCLUDE) CC = arm-none-linux-gnueabi-gcc AR = arm-none-linux-gnueabi-ar RANLIB = arm-none-linux-gnueabi-ranlib CONFIG_H = include/SDL_config.h TARGET = libSDL.a SOURCES = \ src/*.c \ src/audio/*.c \ src/cdrom/*.c \ src/cpuinfo/*.c \ src/events/*.c \ src/file/*.c \ src/joystick/*.c \ src/stdlib/*.c \ src/thread/*.c \ src/timer/*.c \ src/video/*.c \ src/audio/dsp/*.c \ src/audio/dma/*.c \ src/video/fbcon/*.c \ src/joystick/dummy/*.c \ src/cdrom/dummy/*.c \ src/thread/pthread/*.c \ src/timer/unix/*.c \ src/loadso/dlopen/*.c \ OBJECTS = $(shell echo $(SOURCES) | sed -e ’s,\.c,\.o,g’) all: $(TARGET) $(TARGET): $(CONFIG_H) $(OBJECTS) $(AR) crv $@ $^ $(RANLIB) $@ $(CONFIG_H): cp $(CONFIG_H).default $(CONFIG_H) clean: rm -f $(TARGET) $(OBJECTS) |
最后将$SDL\include\SDL_config_minimal.h的内容改成如下:
#ifndef _SDL_config_minimal_h #define _SDL_config_minimal_h #include “SDL_platform.h” #include typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; typedef unsigned int size_t; //typedef unsigned long uintptr_t; #define HAVE_LIBC 1 #ifdef HAVE_LIBC #define HAVE_ALLOCA_H 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_STDIO_H 1 #define STDC_HEADERS 1 #define HAVE_STDLIB_H 1 #define HAVE_STDARG_H 1 #define HAVE_MALLOC_H 1 #define HAVE_MEMORY_H 1 //#define HAVE_STRING_H 1 //#define HAVE_STRINGS_H 1 #define HAVE_INTTYPES_H 1 #define HAVE_STDINT_H 1 #define HAVE_CTYPE_H 1 #define HAVE_MATH_H 1 //#define HAVE_ICONV_H 1 #define HAVE_SIGNAL_H 1 #define HAVE_ALTIVEC_H 1 #define HAVE_MALLOC 1 #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 #define HAVE_FREE 1 #define HAVE_ALLOCA 1 #define HAVE_GETENV 1 #define HAVE_PUTENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 #define HAVE_ABS 1 //#define HAVE_BCOPY 1 //#define HAVE_MEMSET 1 //#define HAVE_MEMCPY 1 //#define HAVE_MEMMOVE 1 //#define HAVE_MEMCMP 1 //#define HAVE_STRLEN 1 //#define HAVE_STRLCPY 1 //#define HAVE_STRLCAT 1 //#define HAVE_STRDUP 1 #define HAVE__STRREV 1 #define HAVE__STRUPR 1 #define HAVE__STRLWR 1 //#define HAVE_INDEX 1 #define HAVE_RINDEX 1 //#define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 #define HAVE_ITOA 1 #define HAVE__LTOA 1 #define HAVE__UITOA 1 #define HAVE__ULTOA 1 #define HAVE_STRTOL 1 #define HAVE_STRTOUL 1 #define HAVE__I64TOA 1 #define HAVE__UI64TOA 1 #define HAVE_STRTOLL 1 #define HAVE_STRTOULL 1 #define HAVE_STRTOD 1 #define HAVE_ATOI 1 #define HAVE_ATOF 1 #define HAVE_STRCMP 1 #define HAVE_STRNCMP 1 #define HAVE__STRICMP 1 #define HAVE_STRCASECMP 1 #define HAVE__STRNICMP 1 #define HAVE_STRNCASECMP 1 #define HAVE_SSCANF 1 #define HAVE_SNPRINTF 1 #define HAVE_VSNPRINTF 1 //#define HAVE_ICONV #define HAVE_SIGACTION 1 #define HAVE_SETJMP 1 #define HAVE_NANOSLEEP 1 //#define HAVE_CLOCK_GETTIME 1 #define HAVE_DLVSYM 1 #define HAVE_GETPAGESIZE 1 #define HAVE_MPROTECT 1 #else #include #endif //#define HAVE_STDIO_H 1 //#define HAVE_STDINT_H 1 //#define SDL_INPUT_TSLIB 1 //touch screen input #define SDL_AUDIO_DRIVER_OSS 1 // SDL_AUDIO_DRIVER_DUMMY #define SDL_CDROM_DISABLED 1 #define SDL_JOYSTICK_DISABLED 1 #define SDL_LOADSO_DLOPEN 1 //SDL_LOADSO_DISABLED 1 //#undef #define SDL_THREAD_PTHREAD 1 //SDL_THREADS_DISABLED //SDL_TIMERS_DISABLED #define SDL_TIMER_UNIX 1 // SDL_VIDEO_DRIVER_DUMMY #define SDL_VIDEO_DRIVER_FBCON 1 #endif |
注意黑体部分,其实就是打开一些宏定义,将SDL的实现一一打开。
改完了这些以后,还需要改一些代码,主要是video方面的,因为Android Linux的framebuffer设备文件与标准Linux不同,Linux的fb设备文件一般是 /dev/fb0,但Android的设备文件是 /dev/graphics/fb0,打开 $SDL/src/video/fbcon/SDL_fbvideo.c,将191、499行的 “/dev/fb0” 替换成 “/dev/graphics/fb0“,保存即可。
再修改 $SDL/src/thread/pthread/SDL_sysmutex.c,将第30行改成: #define FAKE_RECURSIVE_MUTEX 1,就是在后面加一个“1”子,这可能是编译器的一个bug,define默认应该就是“1”的。
现在可以开始编译libSDL.a了,在cygwin或Linux下,进入SDL目录,输入:
make -f Makefile.minimal
视情况面定,一般几分钟后能顺利编译 Android版的 SDL,编译成功后,就需要编译几个SDL的test demo来测试一下 SDL的性能。
进入 test目录,复制 Makefile.in 文件,并改名为 Makefile,将前面一点内容改为:
# Makefile to build the SDL tests srcdir = . INCLUDE = -I../include CC = arm-none-linux-gnueabi-gcc EXE = CFLAGS = -g -s -O2 $(INCLUDE) -static LIBS = -L.. -lSDL -lpthread MATHLIB = -lm |
并将所有的 @MATHLIB@ 替换成 $(MATHLIB),保存后,先编译一个testsprite demo,在命令行输入:
make testsprite
编译成功后,启动Android模拟器,将编译出来的testsprite及icon.bmp上传至一个目录,如 /dev/sample,命令如下:
adb push testspirte /dev/sample/testsprite adb push icon.bmp /dev/sample/icon.bmp |
最后进入 android 的shell: adb shell,再进入 /dev/sample目录,执行testsprite demo即可:
#cd /dev/sample #chmod 755 testsprite #./testsprite -width 320 -height 480 -bpp 32 |
可以根据模拟器的设置调整 width 及 height,因为程序默认的是 640×480的,初始化时会失败,如果一切正常的话,模拟器就会出现很多黄色的笑脸!按任意键退出,在本人机器上能达到 60 FPS左右,效果图如下:
其他的 demo有兴趣的朋友可以自己编译测试。
标签:Android, lib, sdl
发布在 Gphone | 评论关闭
转载: Android原生(Native)C开发之五 zlib移植笔记
2009年02月25日,星期三
zlib(http://www.zlib.net)是一套非常流行的且开源的压缩、解压缩库,由Jean-loup Gailly与Mark Adler所开发,初版0.9版在1995年5月1日发表。zlib使用DEFLATE演算法,最初是为libpng函式库所写的,后来普遍为许多软体所使用。
zlib当前版本是 1.2.3,其移植性非常好,本人已经在Windows、Linux、WinCE、Symbian等平台成功地移植了zlib,当然也包括今天要移植的平台:Android。
首先,从zlib 的官方网站下载zlib的源代码:zlib123.zip,解压后得到一个目录zlib-1.2.3,zib已经提供好了一个Makefile,改动几行(19、20、27、36、37)就可以动手编译了,改动如下:
…… CC = arm-none-linux-gnueabi-gcc CFLAGS = -O2 …… LDFLAGS=libz.a -s -static …… AR = arm-none-linux-gnueabi-ar rc RANLIB = arm-none-linux-gnueabi-ranlib …… |
进入zlib-1.2.3目录,在命令行输入:make 即可。
最后会生成两个可Android可执行文件: example 、minigzip 。
运行Android模拟器, 进入命令行,将两个可执行文件 push 至Android模拟器,再执行,命令如下:
$adb push example /dev/sample/example $adb push minigzip /dev/sample/minigzip $adb shell chmod 777 /dev/sample/* $adb shell #cd /dev/sample #./example zlib version 1.2.3 = 0×1230, compile flags = 0×55 uncompress(): hello, hello! gzread(): hello, hello! gzgets() after gzseek: hello! inflate(): hello, hello! large_inflate(): OK after inflateSync(): hello, hello! inflate with dictionary: hello, hello! #ls -l ls -l -rwxrwxrwx root root 513228 2008-11-10 04:18 minigzip -rwxrwxrwx root root 517640 2008-11-10 04:18 example -rwxrwxrwx root root 31 2008-11-10 04:28 foo.gz #exit $adb pull /dev/sample/foo.gz d:/foo.gz |
其中,“$”是Linux或Cygwin命令行的提示符,#是Android命令行的提示符。
最后,用 ls -l 命令查看当前目录,会发现一个 foo.gz的文件,这个文件就是example生成的,退出adb shell,用命令: adb pull /dev/sample/foo.gz d:/foo.gz 可将模拟器上生成的文件 foo.gz pull至D盘根目录,用winrar或7zip可查看这个文件的内容,正是代码中所写的“hello, hello! ”!
至此,zlib移植Android平台运行成功!
标签:Android, lib
发布在 Gphone | 一条评论 »
转载: Android原生(Native)C开发之六 libpng移植笔记
2009年02月25日,星期三
libpng(http://www.libpng.org/)是读取PNG(Portable Network Graphic Format)文件的最官方的函数库,所以在介绍libpng之前,有必要先介绍下PNG文件。
PNG是20世纪90年代中期开始开发的图像文件存储格式,其目的是企图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。流式网络图形格式(Portable Network Graphic Format,PNG)名称来源于非官方的“PNG’s Not GIF”,是一种位图文件(bitmap file)存储格式,读成“ping”。PNG用来存储灰度图像时,灰度图像的深度可多到16位,存储彩色图像时,彩色图像的深度可多到48位,并且还可存储多到16位的α通道数据。PNG使用从LZ77派生的无损数据压缩算法。
PNG用了无损数据压缩算法,用的压缩库上是上一篇介绍的zlib,编译libpng前,要先编译zlib(请参见上一篇:Android原生(Native)C开发之五:zlib移植笔记)。
先从sourceforge下载libpng的最新版本:1.2.33,请选择without config script版本:bz2格式,zip格式,这个版本没有configure文件,因为基本上不需要改动libpng的设置,就能编译通过。
将下载的源码包解开,得到时一个名为 libpng-1.2.33 的目录,将 scripts\makefile.gcc 复制到 libpng-1.2.33\Makefile,将此文件的 8 – 27 行改成如下即可(粗体为增加部分):
… ZLIBINC = ../zlib-1.2.3 ZLIBLIB = ../zlib-1.2.3 # Compiler, linker, lib and other tools CC = arm-none-linux-gnueabi-gcc LD = $(CC) AR_RC = arm-none-linux-gnueabi-ar rcs RANLIB = arm-none-linux-gnueabi-ranlib RM_F = rm -f CDEBUG = -g -DPNG_DEBUG=5 LDDEBUG = CRELEASE = -O2 LDRELEASE = -s -static #CFLAGS = -W -Wall $(CDEBUG) CFLAGS = -W -Wall $(CRELEASE) #LDFLAGS = $(LDDEBUG) LDFLAGS = $(LDRELEASE) LIBS = -lz -lm … |
在Cygwin或Linux命令行方式进入libpng-1.2.33目录,输入: make 即可成功编译libpng,得到时的静态库libpng.a及可执行文件 pngtest。
用 emulator -noskin 命令启动 Android 模拟器,将pngtest上传到模拟器,即可测试pngtest:
$adb shell mkdir /dev/sample $adb push pngtest /dev/sample $adb push pngtest.png /dev/sample $adb shell chmod 777 /dev/sample/pngtest $adb shell #cd /dev/sample #./pngtest pngtest.png Testing libpng version 1.2.33 with zlib version 1.2.3 libpng version 1.2.33 – October 31, 2008 Copyright (c) 1998-2008 Glenn Randers-Pehrson Copyright (c) 1996-1997 Andreas Dilger Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. library (10233): libpng version 1.2.33 – October 31, 2008 pngtest (10233): libpng version 1.2.33 – October 31, 2008 sizeof(png_struct)=984, sizeof(png_info)=288 Testing pngtest.png: Pass 0: rwrwrwrwrwrwrwrwrw Pass 1: rwrwrwrwrwrwrwrwrw Pass 2: rwrwrwrwrwrwrwrw Pass 3: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw Pass 4: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw Pass 5: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw rwrwrwrw Pass 6: rwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrwrw rwrwrwrwrw PASS (9782 zero samples) Filter 0 was used 21 times Filter 1 was used 15 times Filter 2 was used 52 times Filter 3 was used 10 times Filter 4 was used 33 times tIME = 7 Jun 1996 17:58:08 +0000 libpng passes test |
其中”$”为cygwin的命令提示符,”#”为 adb shell的命令提示符,测试如下图所示:
转载自:http://blog.sina.com.cn/s/blog_4a0a39c30100b8w6.html