【Linux】Linux GNOME 下的Platform libraries - GLib初探

前言

GLib 是Linux下基于C语言实现的Library, 包含常用的数据结构和常用的工具.
GLib 官网链接

常用的GLib Utilities(官网的英文解释更能表达意思,在这里就没有进行过多的翻译)

  • String Utility Functions — various string-related functions,也就是字符串相关的操作.
  • Base64 Encoding — encodes and decodes data in Base64 format
  • Data Checksums — computes the checksum for data
  • File Utilities — various file-related functions,不用在基于Linux 原生API进行文件操作的应用开发
  • UNIX-specific utilities and integration — pipes, signal handling

GLib Core Application Support(列出来了常用到的Application,本质上也是库)

  • The Main Event Loop — manages all available sources of events, 这个事件驱动的机制,是本文讲解的重点.
  • Threads — portable support for threads, mutexes, locks, conditions and thread private data, 但这一点如果是C++编程的话,可以直接用C++提供的库,可以不需要基于这里的Thread进行二次开发
  • Dynamic Loading of Modules — portable method for dynamically loading ‘plug-ins’
  • Memory Allocation — general memory-handling
GLib 初探
The Main Event Loop 介绍

在这里主要是基于GLib相关库实现的一个入门的Main Event Loop的例子来带大家开始了解GLib所带来的开发便捷.

The Main Event Loop 的基本介绍(Copy自GLib官网):

The main event loop manages all the available sources of events for GLib and GTK+ applications. These events can come from any number of different types of sources such as file descriptors (plain files, pipes or sockets) and timeouts. New types of event sources can also be added using g_source_attach().

实质上就是提供了一个异步的、事件驱动的机制和相关Library.

示例代码

接下来下面展示的代码是基于C++实现的.
The Main Event Loop 的例子源码文件构成:

.
├── GLibExample.cpp
├── GLibExample.h
├── main.cpp
├── Makefile
└── README.md
0 directories, 5 files

该示例代码的github仓库路径: GLib Example
GLibExample.cpp/GLibExample.h 为该示例类的实现,主要是调用了gio.h中提供的The Main Event Loop 相关API,进行Event Loop的实现,
main.cpp 中是实例化了GLibExample,进行Demo演示.

GLibExample.h的实现,

#include <gio/gio.h>
#include <future>
#include <thread>
#include <memory>

namespace glib{

class GLibExample{

public:
    static std::shared_ptr<GLibExample> create();
    void SourceEventTest();

private:
    bool init();

    /// Thread procedure to setup and handle GLib events
    void mainLoopThread();
	
    ///
    
    static gboolean onEventCallback(gpointer pointer);

    /// Event loop to listen for signals.
    GMainLoop* m_eventLoop;

    /// GLib context to run event loop in.
    GMainContext* m_workerContext;

    /// Promise to hold the result of a glib's main loop thread initialization.
    std::promise<bool> m_mainLoopInitPromise;

    /// Thread to run event listener on.
    std::thread m_eventThread;
}; 

}

GLibExample.cpp的实现,

#include "GLibExample.h"
#include <iostream>
namespace glib{


std::shared_ptr<GLibExample> GLibExample::create(){

    auto glib_example = std::shared_ptr<GLibExample>(new GLibExample);

    glib_example->init();

    return glib_example;
}


bool GLibExample::init(){
    std::cout << "GLibExample::init" << std::endl;

    m_workerContext = g_main_context_new();

    if (nullptr == m_workerContext) {
        return false;
    }

    m_eventLoop = g_main_loop_new(m_workerContext, false);
    if (nullptr == m_eventLoop) {
        return false;
    }

    m_eventThread = std::thread(&GLibExample::mainLoopThread, this);
 
    return true;
}

void GLibExample::mainLoopThread(){
    g_main_context_push_thread_default(m_workerContext);
    do{
        std::cout << "mainLoopThread running" << std::endl;
        g_main_loop_run(m_eventLoop);
    }while(false);

}

void GLibExample::SourceEventTest(){
    
    auto source = g_idle_source_new();
    g_source_set_callback(source, reinterpret_cast<GSourceFunc>(&onEventCallback), this, nullptr);
    g_source_attach(source, m_workerContext);
    g_source_unref(source);
}

gboolean GLibExample::onEventCallback(gpointer pointer) {
    auto glib_example = static_cast<GLibExample*>(pointer);
    std::cout << "onEventCallback"<< std::endl;
    return false;
}

main.cpp的实现,

#include<iostream>
#include"GLibExample.h"
#include <unistd.h>

int main(int argc, char **argv){

    auto example = glib::GLibExample::create();
    std::cout << "***Hi GLib***" << std::endl;
    while(1)
    {
	example->SourceEventTest();
        sleep(1);
    }
}

Makefile文件的实现,


all:
	g++ GLibExample.cpp main.cpp -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0 -lpthread -o GLib_EventLoop_Example


clean:
	@if [ -e GLib_EventLoop_Example ];then rm GLib_EventLoop_Example;fi
示例代码编译运行
  1. 首先需要安装GLib的相关库和头文件
    在这里演示的是ubuntu下的安装
sudo apt-get install glib2.0
glib2.0提供gio.h  glib.h等头文件和相关so库.
  1. 打开Linux下的终端通过git clone命令下载该example的源码.
➜  glib git clone https://github.com/TracyLaiMan/GLib_Example.git
Cloning into 'GLib_Example'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 12 (delta 1), reused 12 (delta 1), pack-reused 0
Unpacking objects: 100% (12/12), done.

然后cd进行example的目录,

➜  glib ls
GLib_Example
➜  glib cd GLib_Example 
➜  GLib_Example git:(master) ls
GLibExample.cpp  GLibExample.h  main.cpp  Makefile  README.md
➜  GLib_Example git:(master) 

直接在该example的顶层目录运行make命令,

➜  GLib_Example git:(master) make
g++ GLibExample.cpp main.cpp -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0 -lpthread -o GLib_EventLoop_Example
➜  GLib_Example git:(master) ls
GLib_EventLoop_Example  GLibExample.cpp  GLibExample.h  main.cpp  Makefile  README.md

编译成功后,会在目录下生成可执行程序GLib_EventLoop_Example,然后运行测试,

➜  GLib_Example git:(master) ./GLib_EventLoop_Example 
GLibExample::init
***Hi GLib***
mainLoopThread running
onEventCallback
onEventCallback
onEventCallback
onEventCallback
onEventCallback
总结

GLib提供的相关机制不仅可以在Linux主机上的项目中集成进行应用开发,也可以通过交叉编译在我们的目标板上(跑Linux)进行集成应用, 例如Cortex A57等Arm板子上.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值