DirectFB::->Fusion简介

本文深入解析DirectFB中Fusion进程间通信机制的应用,包括Arena的使用、Call的调用、Object的管理、Property的利用、Reactor的追踪、Vector的容器功能及SharedMemoryPool的配置。详细阐述了Fusion在多进程和单进程环境下的工作流程,以及其在DirectFB中的具体实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     Fusion是DFB实现的一个进程间通信的机制。它提供了一系列抽象模块/对象的实现。这些抽象模块都是使用多线程、多进程编程必要的模块。这些模块主要有以下几种:

    (1)共享内存(shared memory);fusion的共享内存是基于GNU malloc在用户空间实现的,但是它mmap到一个基于ram的文件系统(tmpfs或shmfs),该文件系统可作为共享堆内存(share heap)的后备仓库(backing store).每个进程的mmap的起始地址都是0x20000000,因此指向内存分配的指针就可以方便的在进程间传递,而不需要经过复杂的转换。

    (2)竞技场(Arena),它是共享内存的指针注册中心。可以理解为它是一个跨进程的仓库,用来存储所有指向共享内存的指针。通常,我们把这些指针按域fields分类存放在竞技场里。指针通过fields取得。fields域名和竞技场都由你选择的一个竞技场内唯一的名字name来区分。可见,竞技场的的主要功能是对共享数据的管理,通过一个名称与一块数据关联起来,放到hash表中,每个进程都可以通过名字取相应的数据。.fusion_arena_enter()负责创建或者访问指定的Arena,并可以使用回调函数 initialize()和 join() (分别创建新的field和访问field)。例如:

         /* Register shared data. */
     fusion_arena_add_shared_field( arena, "Core/Shared", shared );

      /* Get shared data. */
     fusion_arena_get_shared_field( arena, "Core/Shared", &field )

     (3)引用计数器;

     (4)Skirmish,类似于mutex.

     (5)Call。Fusion call是一种共享函数的方式,该函数可以被其他进程来执行。它是一种远程过程调用机制(RPC)。

      (6)反应器Reactor. Reactor追踪一系列回调函数。当它接到“dispatch”的通知,就会调用这些回调函数。这些callback被称为reactions(反应)。Reactions是与reactors绑定(attached)在一起的.

       (7) 财产(Property).可以把property理解为一个具有特殊语意的锁。该锁你允许你要么暂时拥有这个锁,要么半永久的拥有它。短暂的拥有,我们称之为租赁(lease);半永久的持有,我们称之为购买(purchase).如果property尚无主人,则认为它是可用的(available).当property可用时,你就有机会拥有它。

      (8)向量Vector。Vector是指针的容器。这些指针通常被称为元件(elements).vector跟数组类似,但是vector的元件是打包在一起的,只要某个元件的索引小于元件个数,那么这个元件就在vector里存在。添加一个元件时,元件将获得一个空闲的索引index;删除一个元件时,剩下的元件会依次挪动位置来填补这个元件所占的索引。

 

     理解Fusion,需要从用户空间和内核空间两个方面去把握:

    (1)在用户空间,fusion library库被DFB或其他程序调用;

     (2)在内核空间,实现了fusion device,这些device被库使用,从而实现进程间的通信。

     FUSION通常配置成一个支持多进程的库,它使用内核模块的软设备实现多进程通信。Fusion也可以配置成使用单进程,使用pthread的mutex等构建相关的概念。单进程的情况下,只用到了用户空间的fusion library,它与内核空间的fusion device无关。

      使用fusion library的一个进程通常被称为一个fusionee.Fusionee可以访问它自己创建的fusion item项,也可以访问同处一个fusion world的其他fusionee.多进程环境下,一个world可以包含任意多的进程,而一个系统最多可以有8个world。单进程环境下,每个fusionee都在它自身的world里运作,因此自使用fusion作为内部通信(可能是线程间的通信,但都是限制于同一个进程的线程)。

       每个fusion world 拥有一个file-backed heap(请参看前面讲到的共享内存模块).每个fusion library实例只有一个shared heap. 

 

Fusion 在DirectFB中的应用
初始化:在dfb_core_create()---------------------------->>> fusion_enter()中mmap共享区域,创建world,  初始化共享内存部分,创建Fusion Main Pool, 启动fusion_dispatch_loop
 
1.arena 的使用
      进入或创建名称为"DirectFB/Core" 的arena:
     fusion_arena_enter(...dfb_core_arena_initialize,dfb_core_arena_join...)
     core has one field point to core->share named with "Core/Shared"
     fusion_arena_add_shared_field (in dfb_core_arena_initialize)
    session=<num>                  Select multi app world (zero based, -1 = new)
    环境变量DIRECTFB_SESSION可以设置session的值,
 
2.call 的使用
system>>dfb_gdl_call_handler
input>>input_device_call_handler
fusion.object>>object_reference_watcher
fbdev.c>>fbdev_ioctl_call_handler
 
3.object 的使用
layer_context_pool
layer_region_pool
palette_pool
surface_pool
window_pool
 
4.property 的使用
src/core/gfxcard.c
GraphicsDeviceShared.lock
 
5.reactor 的使用
src/core/input.c
InputDeviceShared.reactor
 
6.vector 的使用
wm/default/default.c
src/core/layers.c
src/core/layer_context.c
 
7.shared memory pool 的使用
src/core/core.c 管理了两个shmpool
DirectFB Main Pool
DirectFB Surface Pool
each world has most 4 shmpool,/dev/shm/fusion.0.x which /dev/shm is tmpfs mount point find in /proc/

 文中后半部分参考了网络文章。

    

<think>好的,我现在要解决用户遇到的这个编译错误:/home/gwj/软件/LibUsbForm/mainform.cpp:61: error: no matching function for call to ‘QLabel::setPixmap(QImage&)’ ui->label->setPixmap(image); ^。首先,我需要理解这个错误的原因。用户试图将一个QImage对象直接传递给QLabel的setPixmap方法,但显然没有匹配的函数。 首先,我应该回忆一下Qt中QLabel的setPixmap方法接受的参数类型。我记得setPixmap需要的是QPixmap类型,而不是QImage。所以问题出在这里,用户传递的是QImage,而应该先转换成QPixmap。 接下来,我需要确认如何正确地将QImage转换为QPixmap。Qt中通常的做法是使用QPixmap的静态方法fromImage,或者直接构造一个QPixmap对象并传入QImage。例如,可以使用QPixmap::fromImage(image)来转换,或者用QPixmap的构造函数QPixmap(image)(如果构造函数支持的话)。不过更常见的是使用fromImage方法。 然后,我需要检查用户的代码,看看是否有这样的转换。用户当前的代码是ui->label->setPixmap(image);,这里的image是QImage类型。因此,正确的做法应该是将image转换为QPixmap后再传入setPixmap。修改后的代码应该是ui->label->setPixmap(QPixmap::fromImage(image));。 另外,我还要考虑是否有其他可能性,比如Qt版本的问题,或者是否有重载函数存在。不过根据错误信息,确实是没有匹配的函数,所以最可能的原因就是类型不匹配,没有直接接受QImage的setPixmap方法。 可能用户会问为什么需要这样的转换,这时候需要解释QImage和QPixmap的区别。QImage主要用于图像处理,而QPixmap用于界面显示,两者用途不同,转换是必要的步骤。 最后,要确保用户修改后的代码能正确编译,并建议在转换时注意图像格式是否兼容,以及是否需要调整大小或缩放等后续处理。</think>在Qt框架中,$\texttt{QLabel::setPixmap()}$ 函数的参数类型必须是 $\texttt{QPixmap}$,而你传递了一个 $\texttt{QImage}$ 类型的对象,导致类型不匹配错误。以下是逐步解决方案: --- ### **错误原因分析** - $\texttt{QImage}$ 是用于图像数据**存储和访问**的类(支持像素级操作)。 - $\texttt{QPixmap}$ 是专为**界面显示优化**的类(适合在屏幕上渲染)。 - 二者用途不同,需显式转换后才能互相使用。 --- ### **修复步骤** 1. **将 $\texttt{QImage}$ 转换为 $\texttt{QPixmap}$** 使用 $\texttt{QPixmap::fromImage()}$ 静态方法: ```cpp ui->label->setPixmap(QPixmap::fromImage(image)); ``` 2. **完整代码示例** ```cpp // 假设 image 是已存在的 QImage 对象 QPixmap pixmap = QPixmap::fromImage(image); ui->label->setPixmap(pixmap); // 或简化为一行: ui->label->setPixmap(QPixmap::fromImage(image)); ``` --- ### **扩展说明** - **性能优化**:若需频繁修改图像内容,可保留 $\texttt{QImage}$ 进行像素操作,仅在更新显示时转换为 $\texttt{QPixmap}$。 - **格式兼容性**:若 $\texttt{QImage}$ 的格式不被硬件支持(如透明通道),转换时需指定格式: ```cpp QPixmap::fromImage(image.convertToFormat(QImage::Format_RGB32)); ``` --- ### **常见疑问** **Q:为何Qt要区分 $\texttt{QImage}$ 和 $\texttt{QPixmap}$?** A:$\texttt{QPixmap}$ 依赖底层图形系统(如X11或DirectFB),专为渲染优化;$\texttt{QImage}$ 独立于硬件,保证跨平台像素操作的准确性。 --- 修改后代码应能正常编译。如果问题依旧,请检查 $\texttt{image}$ 对象是否已正确初始化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值