嵌入式系统终端分析

news/2024/7/8 2:09:51 标签: 终端, 嵌入式, struct, c, timer, null
cle class="baidu_pl">
cle_content" class="article_content clearfix">
content_views" class="htmledit_views">

class="tags" href="/tags/QianRuShi.html" title=嵌入式>嵌入式系统class="tags" href="/tags/ZhongDuan.html" title=终端>终端分析
 
 
 
------------------------------------
本文系本站原创,欢迎转载!

转载请注明出处:http://sjj0412.cublog.cn/
------------------------------------------ 
当我们打开机器或一个class="tags" href="/tags/QianRuShi.html" title=嵌入式>嵌入式系统时࿰c;我们可能都适应了它会显示信息࿰c;我们也理所当然?
娜衔馐怯Ω茫撬蛹扑慊型ü嗌俟乜诓诺酱锵允酒骰虼谥斩讼允镜哪兀兰?
大家都没在意过࿰c;其实这个过程在linux
操作系统中可为千辛万库啊࿰c;当然在其他操作系统也一样࿰c;今天我就来分析从printf
到显示设备的过程。

  我们先来看下面这些程序。

1  If (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)

              printk(KERN_WARNING "Warning: unable to open an initial console
./n");

 

2  (void) sys_dup(0);

3  (void) sys_dup(0);   

第1语句执行后生成第一个文件࿰c;这个文件的文件号为0࿰c;第2
语句过后产生第二个文件࿰c;这个文件的文件号为1࿰c;第3
语句过后产生第三个文件࿰c;这个文件的文件号为2
c;这时这三个文件都指向同一个文件࿰c;那就是设备文件/dev/console
c;这个三个文件就是大名鼎鼎的标准输入࿰c;标准输出࿰c;错误输出文件࿰c;当然他们有不同属?
裕罄床鸥模院蠖哉庑┪募诺牟僮骶褪嵌?dev/console
的操作࿰c;由于所有进程是由这个进程fork
继承而来࿰c;故所有进程都拥有这些文件号࿰c;都可以执行写读操作࿰c;即向显示设备输出内容?
淙肷璞付寥肽谌荨?

在上面语句没有执行前都是通过printk来输出字符࿰c;printk是不通过文件系统输出字符的

c;而直接通过相关驱动输出到显示设备࿰c;执行这些语句后࿰c;大家就可以通过向0
号文件写入或读入内容(write(0,buf,len))来达到输出字符的目的,
也许你会说我们没有用这个write
函数啊࿰c;其实是操作系统帮你调用这个函数的࿰c;也许大家经常在应用程序用printf
c;这个函数就会调用系统调用write(0,buf,len)等等。

应用层分析就到此位置࿰c;但是设备层又来了。

当我们向/dev/console
设备文件写或读入数据࿰c;怎么就在显示设备上(没有在串口中)显示了࿰c;并且在Pc
上它是在显示器上显示࿰c;在arm
class="tags" href="/tags/QianRuShi.html" title=嵌入式>嵌入式设备上࿰c;往往是在串口中显示(当然要超级class="tags" href="/tags/ZhongDuan.html" title=终端>终端或minicom)࿰c;难道/dev/
console很智能࿰c;对它确实很智能࿰c;要分析这个过程࿰c;就不得不谈到class="tags" href="/tags/ZhongDuan.html" title=终端>终端的概念。

1.      一般class="tags" href="/tags/ZhongDuan.html" title=终端>终端

2.      控制台class="tags" href="/tags/ZhongDuan.html" title=终端>终端

3        pts

控制台class="tags" href="/tags/ZhongDuan.html" title=终端>终端是class="tags" href="/tags/ZhongDuan.html" title=终端>终端的一种࿰c;如/dev/tty0,/dev/tty1࿰c;…./dev/tty8
等虚拟控制台class="tags" href="/tags/ZhongDuan.html" title=终端>终端࿰c;其中/dev/tty0叫当前控制台class="tags" href="/tags/ZhongDuan.html" title=终端>终端࿰c;它通常指向/dev/tty1,…../dev/
tty8中的一个࿰c;/dev/tty
是进程的class="tags" href="/tags/ZhongDuan.html" title=终端>终端࿰c;它可以是控制台class="tags" href="/tags/ZhongDuan.html" title=终端>终端也可以是其他class="tags" href="/tags/ZhongDuan.html" title=终端>终端࿰c;反正它就是进程拥有的class="tags" href="/tags/ZhongDuan.html" title=终端>终端。

现在开始非常重要的class="tags" href="/tags/ZhongDuan.html" title=终端>终端到了࿰c;那就是/dev/console
有很多人将它说成是外接控制台class="tags" href="/tags/ZhongDuan.html" title=终端>终端࿰c;我不理解࿰c;我认为它就是用来输出信息(应用程序
printf使用)的class="tags" href="/tags/ZhongDuan.html" title=终端>终端。我们知道

 

在pc中我们的控制台就是/tty1,……/tty..,我们应该记得ctrl+alt+fn
来切换控制台吧࿰c;这个时候这些控制台就是对应/dev/tty1……/dev/tty4,
这个时候这些控制台就是用来输出信息的࿰c;照这样说来࿰c;/dev/console应该是指向/dev/
tty*中的一个,事实上是对的࿰c;我们可以在Linux
文本模式下实验࿰c;在第一个控制台࿰c;我们输入

echo “kfdl”>/dev/tty0,echo “kfds”>/dev/tty1࿰c;echo”kfdl”>/dev/console
这三调命令都可以在屏幕下看到信息࿰c;这说明这三个设备文件都引导到了同一个
tty_driver࿰c;tty_class="tags" href="/tags/STRUCT.html" title=struct>struct,

然后按ctrl+alt+f2,进入另一个控制࿰c;

echo “kfdl”>/dev/tty0,echo “kfds”>/dev/tty2࿰c;echo”kfdl”>/dev/console
c;仍然可以看到信息࿰c;但输入/dev/tty1输出不了信息࿰c;为什么,因为这个是控制台2
了啊࿰c;而console有机制可以指向活动的tty,所以可以显示࿰c;当然/dev/tty0
本身就是指向活动的控制台的。

在armclass="tags" href="/tags/QianRuShi.html" title=嵌入式>嵌入式系统中࿰c;

我们也可以实验࿰c;但是结果很不一样࿰c;

echo “kfdl”>/dev/tty0,echo “kfds”>/dev/tty1࿰c;echo”kfdl”>/dev/console

中只有echo”kfdl”>/dev/console能输出信息࿰c;这是为什么因为在arm
class="tags" href="/tags/QianRuShi.html" title=嵌入式>嵌入式系统中࿰c;显示信息的不是显示器了࿰c;是串口了࿰c;所以由于console
是引导向显示信息的设备࿰c;而

Tty1-tty4只是控制台(只不过在Pc中恰好就是显示器作为显示它才能显示)࿰c;故只有
console࿰c;当然如果有显示器等显示设别࿰c;echo “kfdl”>/dev/tty0,echo “kfds”>/
dev/tty1可以在显示器等设备显示࿰c;但在串口是如何都不能显示的。

这时如何实现的࿰c;我们知道当我们打开class="tags" href="/tags/ZhongDuan.html" title=终端>终端设备时࿰c;内核的入口就是

Tty设备文件打开关键是找到tty_driver࿰c;因为它里面有具体tty的操作函数啊。

static int tty_open(class="tags" href="/tags/STRUCT.html" title=struct>struct inode *inode, class="tags" href="/tags/STRUCT.html" title=struct>struct file *filp)

{

         class="tags" href="/tags/STRUCT.html" title=struct>struct tty_class="tags" href="/tags/STRUCT.html" title=struct>struct *tty;

         int noctty, retval;

         class="tags" href="/tags/STRUCT.html" title=struct>struct tty_driver *driver;

         int index;

         dev_t device = inode->i_rdev;

         unsigned short saved_flags = filp->f_flags;

 

         nonseekable_open(inode, filp);

 

retry_open:

         //O_NOCTTY 如果路径名指向class="tags" href="/tags/ZhongDuan.html" title=终端>终端设备࿰c;不要把这个设备用作控制class="tags" href="/tags/ZhongDuan.html" title=终端>终端

 

         //noctty:需不需要更改当前进程的控制class="tags" href="/tags/ZhongDuan.html" title=终端>终端

         noctty = filp->f_flags & O_NOCTTY;

         index  = -1;

         retval = 0;

 

         mutex_lock(&tty_mutex);

 

         //设备号(5,0) 即/dev/tty.表示当前进程的控制class="tags" href="/tags/ZhongDuan.html" title=终端>终端

         if (device == MKDEV(TTYAUX_MAJOR, 0)) {//tty设备文件的driver的获取方式

                   tty = get_current_tty();/这就是为什么说tty
代表当前进程class="tags" href="/tags/ZhongDuan.html" title=终端>终端࿰c;代码中就是这样实现的啊

                   //如果当前进程的控制class="tags" href="/tags/ZhongDuan.html" title=终端>终端不存在,退出

                   if (!tty) {

                            mutex_unlock(&tty_mutex);

                            return -ENXIO;

                   }

 

                   //取得当前进程的tty_driver

                   driver = tty->driver;

                   index = tty->index;

                   filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */

                   /* noctty = 1; */

                   goto got_driver;

         }

#ifdef CONFIG_VT

         //设备号(4,0).即/dev/tty0:表示当前的控制台

         if (device == MKDEV(TTY_MAJOR, 0)) {

                   extern class="tags" href="/tags/STRUCT.html" title=struct>struct tty_driver *console_driver;//tty0设备文件的
driver的获取方式

                   driver = console_driver;

                   //fg_console: 表示当前的控制台全局变量(console_driver ,fg-
console)设置了它为活动控制台

                   index = fg_console;

                   noctty = 1;

                   goto got_driver;

         }

#endif

         //设备号(5,1).即/dev/console.表示外接的控制台. 通过regesit_console()

         if (device == MKDEV(TTYAUX_MAJOR, 1)) {

                   driver = console_device(&index);//关键在这里/console
设备文件的driver的获取方式

                   if (driver) {

                            /* Don't let /dev/console block */

                            filp->f_flags |= O_NONBLOCK;

                            noctty = 1;

                            goto got_driver;

                   }

                   mutex_unlock(&tty_mutex);

                   return -ENODEV;

         }

 driver = get_tty_driver(device, &index);//tty1~ttyn设备文件driver获取的方式

       ……….

………….

         return 0;

}

 

console_device致关重要啊:

class="tags" href="/tags/STRUCT.html" title=struct>struct tty_driver *console_device(int *index)

{

  class="tags" href="/tags/STRUCT.html" title=struct>struct console *c;

  class="tags" href="/tags/STRUCT.html" title=struct>struct tty_driver *driver = NULL;

 

  acquire_console_sem();

  for (c = console_drivers; c != NULL; c = c->next) {

         if (!c->device)

                continue;

         driver = c->device(c, index);//console的tty找到了啊

         if (driver)

                break;

  }

  release_console_sem();

  return driver;

}

由上面的红色可知࿰c;console设备的driver由console_drivers获取。

console_drivers是如何赋值的࿰c;

它是通过register_console 注册的。

void register_console(class="tags" href="/tags/STRUCT.html" title=struct>struct console * console)

{

………………………

………………………..

  if ((console->flags & CON_CONSDEV) || console_drivers == NULL) {

         console->next = console_drivers;

         console_drivers = console;

         if (console->next)

                console->next->flags &= ~CON_CONSDEV;

  } else {

         console->next = console_drivers->next;

         console_drivers->next = console;//这些就将console挂到console_drivers
链上了啊

  }

  if (console->flags & CON_PRINTBUFFER) {

         /*

          * release_console_sem() will print out the buffered messages

          * for us.

          */

         spin_lock_irqsave(&logbuf_lock, flags);

         con_start = log_start;

         spin_unlock_irqrestore(&logbuf_lock, flags);

  }

………

………

}

由上可知在Pcconsole和tty0~tty1显示是一样的࿰c;那它的驱动应该是一样的࿰c;也就是说
console_driver->device返回的tty_driver应该是console_driver
c;是如何实现࿰c;这个就是con_init实现的哦࿰c;

static int __init con_init(void)

{

  const char *display_desc = NULL;

  class="tags" href="/tags/STRUCT.html" title=struct>struct vc_data *vc;

  unsigned int currcons = 0;

 

  acquire_console_sem();

 

  if (conswitchp)

         display_desc = conswitchp->con_startup();

  if (!display_desc) {

         fg_console = 0;

         release_console_sem();

         return 0;

  }

 

  init_timer(&console_timer);

  console_timer.function = blank_screen_t;

  if (blankinterval) {

         blank_state = blank_normal_wait;

         mod_timer(&console_timer, jiffies + blankinterval);

  }

 

  /*

   * kmalloc is not running yet - we use the bootmem allocator.

   */

  for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {

         vc_cons[currcons].d = vc = alloc_bootmem(sizeof(class="tags" href="/tags/STRUCT.html" title=struct>struct vc_data));

         visual_init(vc, currcons, 1);

         vc->vc_screenbuf = (unsigned short *)alloc_bootmem(vc->
vc_screenbuf_size);

         vc->vc_kmalloced = 0;

         vc_init(vc, vc->vc_rows, vc->vc_cols,

                currcons || !vc->vc_sw->con_save_screen);

  }

  currcons = fg_console = 0;

  master_display_fg = vc = vc_cons[currcons].d;

  set_origin(vc);

  save_screen(vc);

  gotoxy(vc, vc->vc_x, vc->vc_y);

  csi_J(vc, 0);

  update_screen(vc);

  printk("Console: %s %s %dx%d",

         vc->vc_can_do_color ? "colour" : "mono",

         display_desc, vc->vc_cols, vc->vc_rows);

  printable = 1;

  printk("/n");

 

  release_console_sem();

 

#ifdef CONFIG_VT_CONSOLE

  register_console(&vt_console_driver);//这一句致关重要࿰c;它注册了console
c;挂到了console_driver

#endif

  return 0;

}

再看下vt_console_driver的console_device是不是返回console_driver,

static class="tags" href="/tags/STRUCT.html" title=struct>struct console vt_console_driver = {

  .name            = "tty",

  .write             = vt_console_print,

  .device          = vt_console_device,

  .unblank = unblank_screen,

  .flags             = CON_PRINTBUFFER,

  .index            = -1,

};

static class="tags" href="/tags/STRUCT.html" title=struct>struct tty_driver *vt_console_device(class="tags" href="/tags/STRUCT.html" title=struct>struct console *c, int *index)

{

  *index = c->index ? c->index-1 : fg_console;

  return console_driver;

}

console_initcall(con_init);

正是࿰c;大功告成。

下面来看在arm等class="tags" href="/tags/QianRuShi.html" title=嵌入式>嵌入式系统中࿰c;console
是和串口相关练的࿰c;那么应该也有一个类似的注册console的函数࿰c;经发现࿰c;正是啊

在s3c2410.c

tatic int s3c24xx_serial_initconsole(void)

{

  class="tags" href="/tags/STRUCT.html" title=struct>struct s3c24xx_uart_info *info;

  class="tags" href="/tags/STRUCT.html" title=struct>struct platform_device *dev = s3c24xx_uart_devs[0];

 

  dbg("s3c24xx_serial_initconsole/n");

 

  /* select driver based on the cpu */

 

  if (dev == NULL) {

         printk(KERN_ERR "s3c24xx: no devices for console init/n");

         return 0;

  }

 

  if (strcmp(dev->name, "s3c2400-uart") == 0) {

         info = s3c2400_uart_inf_at;

  } else if (strcmp(dev->name, "s3c2410-uart") == 0) {

         info = s3c2410_uart_inf_at;

  } else if (strcmp(dev->name, "s3c2440-uart") == 0) {

         info = s3c2440_uart_inf_at;

  } else {

         printk(KERN_ERR "s3c24xx: no driver for %s/n", dev->name);

         return 0;

  }

 

  if (info == NULL) {

         printk(KERN_ERR "s3c24xx: no driver for console/n");

         return 0;

  }

 

  s3c24xx_serial_console.data = &s3c24xx_uart_drv;

  s3c24xx_serial_init_ports(info);

 

  register_console(&s3c24xx_serial_console);

  return 0;

}

static class="tags" href="/tags/STRUCT.html" title=struct>struct console s3c24xx_serial_console =

{

  .name            = S3C24XX_SERIAL_NAME,

  .device          = uart_console_device,

  .flags             = CON_PRINTBUFFER,

  .index            = -1,

  .write             = s3c24xx_serial_console_write,

  .setup            = s3c24xx_serial_console_setup

};

class="tags" href="/tags/STRUCT.html" title=struct>struct tty_driver *uart_console_device(class="tags" href="/tags/STRUCT.html" title=struct>struct console *co, int *index)

{

  class="tags" href="/tags/STRUCT.html" title=struct>struct uart_driver *p = co->data;

  *index = co->index;

  return p->tty_driver;

}

我们可以知道࿰c;返回的是s3c24xx_uart_drv中的tty_dirver࿰c;这个driver
是何时注册的呢࿰c;

其实这就关系到uart结构

static int __init s3c24xx_serial_modinit(void)

{

  int ret;

 

  ret = uart_register_driver(&s3c24xx_uart_drv);

  if (ret < 0) {

         printk(KERN_ERR "failed to register UART driver/n");

         return -1;

  }

 

  s3c2400_serial_init();

  s3c2410_serial_init();

  s3c2440_serial_init();

 

  return 0;

}

int uart_register_driver(class="tags" href="/tags/STRUCT.html" title=struct>struct uart_driver *drv)

{

     class="tags" href="/tags/STRUCT.html" title=struct>struct tty_driver *normal = NULL;

     int i, retval;

 

     BUG_ON(drv->state);

 

     /*

      * Maybe we should be using a slab cache for this, especially if

      * we have a large number of ports to handle.

      */

     drv->state = kzalloc(sizeof(class="tags" href="/tags/STRUCT.html" title=struct>struct uart_state) * drv->nr, GFP_KERNEL);

     retval = -ENOMEM;

     if (!drv->state)

         goto out;

 

     normal  = alloc_tty_driver(drv->nr);

     if (!normal)

         goto out;

 

     drv->tty_driver = normal;

 

     normal->owner      = drv->owner;

     normal->driver_name    = drv->driver_name;

     normal->name       = drv->dev_name;

     normal->major      = drv->major;

     normal->minor_start    = drv->minor;

     normal->type       = TTY_DRIVER_TYPE_SERIAL;

     normal->subtype        = SERIAL_TYPE_NORMAL;

     normal->init_termios   = tty_std_termios;

     normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;

     normal->init_termios.c_ispeed = normal->init_termios.c_ospeed = 9600;

     normal->flags      = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;

     normal->driver_state    = drv;

     tty_set_operations(normal, &uart_ops);

 

     /*

      * Initialise the UART state(s).

      */

     for (i = 0; i < drv->nr; i++) {

         class="tags" href="/tags/STRUCT.html" title=struct>struct uart_state *state = drv->state + i;

 

         state->close_delay     = 500;    /* .5 seconds */

         state->closing_wait    = 30000;  /* 30 seconds */

 

         mutex_init(&state->mutex);

     }

 

     retval = tty_register_driver(normal);

 out:

     if (retval < 0) {

         put_tty_driver(normal);

         kfree(drv->state);

     }

     return retval;

}

 

从上面可以看到࿰c;当串口注册时它作为一般的tty_driver注册࿰c;但是由于uart_driver
还是console.data࿰c;且在console设备通过console_device然后uart_driver->device
函数会把uart_driver的tty_driver(上面的normal)赋给console故它还是console的
tty_driver
c;这个可以明白࿰c;串口我们当然也希望当作一般的串口接口࿰c;而不仅仅是作为控制class="tags" href="/tags/ZhongDuan.html" title=终端>终端在?
吨斩酥邢允镜摹?

无论是一般tty_driver࿰c;还是console的tty_driver,它的统一接口是uart_opd
c;这就区别了其他tty_driver࿰c;

Tty_driver->driver_data=uart_driver

Uart_open后

Tty_class="tags" href="/tags/STRUCT.html" title=struct>struct->driver_data=uart_state;

 

那s3c24xx_serial_initconsole࿰c;和con_init又是在那调用的呢在start_kernel->
console_init调用的

all = __con_initcall_start;

  while (call < __con_initcall_end) {

         (*call)();

         call++;

  }

__con_initcall_start是一个初始段࿰c;通过console_initcall注册࿰c;

#define console_initcall(fn) /

  static initcall_t __initcall_##fn /

  __attribute_used__ __attribute__((__section__(".con_initcall.init")))=fn

Console_initcall(con_init)

console_initcall(s3c24xx_serial_initconsole);

 

下面讲/dev/tty,/dev/tty0,/dev/console,串口class="tags" href="/tags/ZhongDuan.html" title=终端>终端/tts/0~n(在内核叫做ttySAC0~n
)的产生过程,虚拟控制台class="tags" href="/tags/ZhongDuan.html" title=终端>终端/dev/tty1~ttyn

/dev/tty࿰c;/dev/tty0,/dev/console都是在tty_init中通过cdev_add࿰c;register_chrdev(
)等添加

的࿰c;而/dev/tty~ttyn是在vty_init中通过tty_driver_register创建的࿰c;并且创建
console_driver->num即MAX_NR_CONSOLES࿰c;在alloc_ttydriver是赋值的࿰c;而/tts/0~n
是在s3c24xx_serial_probe中࿰c;当static inline int s3c2440_serial_init(void)

{

  return s3c24xx_serial_init(&s3c2440_serial_drv, &s3c2440_uart_inf);

}

当s3c2440_serial_drv检测到串口设备时就会调用s3c24xx_serial_probe
c;然后它就会通过uart_add_one_port->tty_register_device(由于这个device的dev_t
由它的tty_driver major
指定࿰c;当打开这个设备肯定可以找到这个驱动)创建class="tags" href="/tags/ZhongDuan.html" title=终端>终端的设备࿰c;如果这个些串口class="tags" href="/tags/ZhongDuan.html" title=终端>终端设?
傅膗art_driver->con存在且con.flags=con_enable࿰c;它也同时console_register
c;所以这时console可以指向它们中的任意一个。

 
 

cle>

http://www.niftyadmin.cn/n/1748385.html

相关文章

什么是 jQuery EasyUI

jQuery EasyUI 是一个基于 jQuery 的框架&#xff0c;集成了各种用户界面插件。 jQuery EasyUI 框架提供了创建网页所需的一切&#xff0c;帮助您轻松建立站点。 easyui 是一个基于 jQuery 的框架&#xff0c;集成了各种用户界面插件。easyui 提供建立现代化的具有交互性的 jav…

嵌入式 linux 智能设备应用中 web 支持的实现(一)

嵌入式 linux 智能设备应用中 web 支持的实现(一)由两篇文章组成的系列文章主要阐述如何在嵌入式 Linux 智能设备的应用程序中增加 Web 支持。第 1 部分&#xff0c;我们将会介绍嵌入式 Linux 智能设备开发的现状、Qt 和 WebKit 的概念。并以广告机和手持点菜机等应用为例&…

嵌入式 linux 智能设备应用中 web 支持的实现(二)

嵌入式 linux 智能设备应用中 web 支持的实现(二)由两篇文章组成的系列文章主要阐述如何在嵌入式 Linux 智能设备的应用程序中增加 Web 支持。第 1 部分介绍了如何设备上提供常规 Web 功能的支持。本文是第2部分&#xff0c;将重点介绍如何让在嵌入式设备上运行的 Web 程序能支…

使用LCP建立链路

2.3.5 使用LCP建立链路LCP操作包括链路建立、链路维护和链路终止。1&#xff0e;LCP操作LCP使用3种LCP帧来完成每个LCP阶段的工作。链路建立帧&#xff08;Configure-Request、Configure-Ack、Configure-Nak和Configure-Reject&#xff09;用于建立和配置链路。链路维护帧&…

使用DirecetFB支持Qt4.7.0,加速启动QT

使用DirecetFB支持Qt4.7.0 使用DirecetFB支持Qt4.7.0摘要&#xff1a;如何在ok6410上使用Directfb&#xff0c;并且使用它支持Qt4.7.0关键字&#xff1a;directfb 1.2.8 Qt4.7.0 tslib ok64101&#xff0e;前言&#xff1a;很久之前就已经听说过directFb&#xff0c;但实际上…

html img图片懒加载

2019独角兽企业重金招聘Python工程师标准>>> 参考链接&#xff1a;http://www.w3cways.com/1765.html 转载于:https://my.oschina.net/qimhkaiyuan/blog/856342

Qt WebKit可以做什么

Qt WebKit可以做什么2010-07-13 23:14欢迎看看我的另一个小窝,可能会有意外的惊喜哦^_^ www.devres.info From&#xff1a;http://software.intel.com/zh-cn/blogs/2010/06/08/qt-webkit-qt-webkit/ Author&#xff1a;Dawei Cheng程大伟&#xff08;Intel&#xff09;这个命题…

BZOJ 1531 二进制优化多重背包

思路&#xff1a; 讲道理我应该写单调队列优化多重背包的 但是我不会啊 但是我现在&#xff01; 还不会啊 我就写了个二进制优化的.. 过了 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n,cpy[222],…