原文地址:http://blog.csdn.net/ariesjzj/article/details/7972755
Qemu中翻译的主要框架位于cpu-exec.c中的cpu_exec()函数。
For (;;) {
If (setjmp(env->jmp_env) == 0) {
// exception handling
For (;;) {
// longjmp if there is an exception has been requested
Tb_find_fast() // Look up translation block.
...
Tb_add_jump() // Chaining
...
Tcg_qemu_tb_exec() // Execute the translation block
}
}
}
外循环一开始设jump context为了将来中断处理作准备,内循环中检查是否有中断,有的话跳到前面设置的jump context处,另外内循环中主要做翻译和执行翻译的code。tb_find_fast()用于找要执行的code是否已经被翻译:
Tb_find_fast() // search the fast lookup table(env->tb_jmp_cache)
If not found
Tb_find_slow() // search the slow lookup table(physical page table – tb_phys_hash)
If not found
Tb_gen_code() // do translation
else
// add to fast lookup table
else
return
其中tb_gen_code开始翻译:
Tb_gen_code()
// alloc translation block
Cpu_gen_code()
// add to slow lookup table
Cpu_gen_code()
Gen_intermediate_code() // phase 1
Gen_intermediate_code_internal()
Disas_insn()
Tcg_gen_code // phase 2
Tcg_gen_code_common()
翻译分为两个阶段:
阶段1:guest代码到中间表示(称为micro operation)。这个阶段的实现代码主要在target-ARCH这个目录下,产生结果放在gen_opc_buf(TCG opcode)和gen_opparam_buf(TCG operand)中。
阶段2:中间表示到host代码。这个阶段的实现代码主要在tcg目录下。产生结果放在gen_code_buf中。
翻译完了该执行翻译的代码了:
Tcg_qemu_tb_exec()
Code_gen_prologue // generated by tcg_target_qemu_prologue() when initialization.
Code_gen_prologue
// prologue: callee saved registers, reserve stack space, etc.
// jump to translated code
// epilogue: restore register and stack, etc.
在Android的emulator中,Qemu为我们提供了一些有力的调试工具,如
1. Monitor,这个工具可以让用户在Qemu运行过程中与之交互并且加以控制。首先加启动参数:
$ Emulator.exe –avd test –qemu -monitor telnet::1235,server,nowait
接着用telnet连上:
(telnet) o localhost 1235
然后就应该能看到Qemu shell提示符了。之后就可以运行monitor提供的命令了。
2. Log。启动时加参数-qemu -d可以根据需要打出log:
Log items (comma separated):
out_asm show generated host assembly code for each compiled TB
in_asm show target assembly code for each compiled TB
op show micro ops for each compiled TB
op_opt show micro ops before eflags optimization and after liveness analysis
int show interrupts/exceptions in short format
exec show trace before each executed TB (lots of logs)
cpu show CPU state before block translation
pcall show protected mode far calls/returns/exceptions
cpu_reset show CPU state before CPU resets
比如加in_asm,out_asm就能把guest code和翻译好的host code打印出来:
IN:
0xfffffff0: ljmp $0xf000,$0xe05b
OUT: [size=32]
0x06614020: mov $0xf000,%eax
0x06614025: movzwl %ax,%eax
0x06614028: mov %eax,0x50(%ebp)
0x0661402b: shl $0x4,%eax
0x0661402e: mov %eax,0x54(%ebp)
0x06614031: mov $0xe05b,%eax
0x06614036: mov %eax,0x20(%ebp)
0x06614039: xor %eax,%eax
0x0661403b: jmp 0x844548
一、最终效果图:
注:仅支持ARC,非ARC需要添加部分代码。
二、新建任意类型的项目工程,我这里使用的是Single-View模板。新建工程后,代码添加UITableView,由于本人喜欢使用纯代码编程,因此所有的东西都是用代码实现的。下面是添加UITableView的代码:
ViewController.h文件中添加:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>{
UITableView *_tableView;
NSMutableArray *_titleArray;
NSMutableArray *_itemsArray;
}
@property (nonatomic,strong) UITableView *tableView;
@endViewController.h文件中添加:
@implementation ViewController
@synthesize tableView = _tableView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_titleArray = [[NSMutableArray alloc] initWithObjects:@"Draw Rects",@"Draw Gradients",@"Draw Arcs",nil ];
_itemsArray = [[NSMutableArray alloc] initWithObjects:@"UIKit",@"TableView",@"Objective-C",nil ];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStyleGrouped];
_tableView.delegate = self;
_tableView.dataSource = self;
[self.view addSubview:_tableView];
}
这样就完成了基本的引入添加,但是此时更改不能显示,UITableView的delegate和DataSource相关必须的代码还都没有重写,TableView是空的。
实现下面三个方法:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 2;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if(section == 0){
return _titleArray.count;
}else{
return _itemsArray.count;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
NSString *entry;
if(indexPath.section == 0){
entry = [_titleArray objectAtIndex:indexPath.row];
}else{
entry = [_itemsArray objectAtIndex:indexPath.row];
}
cell.textLabel.text = entry;
cell.textLabel.backgroundColor = [UIColor clearColor];
return cell;
}完成这些后运行工程,就能看到一个基本的列表样式显示了:
重写方法tableView:titleForHeaderInSection方法:
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if(section == 0){
return @"即将学到的...";
}else{
return @"所具备的...";
}
}五、重绘Cell的背景
新建一个基于UIView的子类CustomCellBackView.h,并在子类中打开DrawRect方法,在次方法中绘制背景颜色,这里使用的是Core Graphic绘制方法:
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef redColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0].CGColor;
CGContextSetFillColorWithColor(context, redColor);
CGContextFillRect(context, self.bounds);然后在ViewController.h文件中引入新建的子类并定义为Cell的背景:
引入文件:
#import "ViewController.h" #import "CustomCellBackView.h"定义为Cell的背景:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
cell.backgroundView = [[CustomCellBackView alloc]init];
cell.selectedBackgroundView = [[CustomCellBackView alloc] init];
}
运行后:
在头文件中定义一个方法:
-(void)drawLinerGradient:(CGContextRef)context Rect:(CGRect)rect startColorRef:(CGColorRef)startColor endColorRef:(CGColorRef)endColor;
然后在实现文件中进行详细的绘制:
-(void)drawLinerGradient:(CGContextRef)context Rect:(CGRect)rect startColorRef:(CGColorRef)startColor endColorRef:(CGColorRef)endColor{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = {0.0,1.0};
NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor,(__bridge id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)CFBridgingRetain(colors), locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}这里面用到了很多Core Graphic的方法,以及部分ios5 ARC模式支持的定义,不了解的可以查看Apple API文档。 七、完成之后,在CustomCellBackView.m文件中引入Common.h文件,并重写drawRect方法:
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef redColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0].CGColor;
CGColorRef whiteColor = [UIColor colorWithRed:1.0 green:1.0
blue:1.0 alpha:1.0].CGColor;
CGColorRef lightGrayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0
blue:230.0/255.0 alpha:1.0].CGColor;
CGRect paperRect = self.bounds;
Common *common = [[Common alloc]init];
[common drawLinerGradient:context Rect:paperRect startColorRef:whiteColor endColorRef:lightGrayColor];
//add line stroke
CGRect strokeRect = CGRectInset(paperRect, 5.0, 5.0);
CGContextSetStrokeColorWithColor(context, redColor);
CGContextSetLineWidth(context, 1.0);
CGContextStrokeRect(context, strokeRect);八、运行程序,查看结果:
注:这样就基本完成了一个UITableCell的自定义,但那时这样的样式还是有欠缺,这个效果没有立体感,而且边框线也有点太粗了,剩下的部分留在后面介绍吧。
1、android java(client) 远程获取 (server)端目录结构中文乱码(解决办法)
Server(QT/C++等)
Client(android java)
Server(QT)------发送未编码中文文件名字符序列----> Client(java)
client读取byte[] data序列时通过
String zhStr = new String(data,"GB2312");
Client(java)----发送未编码中文文件名字符序列---> Server(QT)
ByteArray sockData;//从socket数据 "获取文件名字符串"后
Linux或者gcc编译器:转化成UTF-8编码。
Windows VC编译器:转化成gb2312编码。