libuv源码编译,QT工程创建及示例代码

本文介绍了libuv库的基本概念,它是一个用于异步I/O操作的跨平台库,最初为Node.js设计,现在成为独立组件。文章详细展示了如何在QT工程中整合libuvv1.44.1的源码,包括添加依赖文件路径、编译设置以及在Windows和Linux系统下的特定配置。通过示例代码,说明了如何在main.cpp中建立一个简单的TCP服务器来测试libuv的功能。
摘要由CSDN通过智能技术生成

libuv简介

libuv是一个基于事件驱动的跨平台的异步I/O库,它主要提供了异步文件操作、网络操作、定时器、子进程等功能。libuv最初是Node.js的一个组件,用于处理非阻塞I/O的事件循环,后来逐渐发展成为一个独立的库。它支持多种平台,包括Linux, macOS, Windows等,通过统一的API接口,应用程序可以在不同的平台上得到相同的行为。libuv还提供了一套线程池工具,可用于处理一些CPU密集型的任务。在Node.js 10版本之后,libuv被集成到Node.js中,成为了Node.js的重要组成部分。

libuv的下载地址和官方教程如下:

下载地址:

GitHub地址:https://github.com/libuv/libuv/releases

官网下载地址:http://libuv.org/dist/

官方教程:

官方文档:http://docs.libuv.org/en/latest/index.html

GitHub示例代码:https://github.com/libuv/libuv/tree/v1.x/docs/code

常见问题及解答:http://docs.libuv.org/en/stable/faq.html

除了官方文档和示例代码外,还有一些社区提供的教程和文章,可以通过互联网搜索来获得更多的学习资源。

本文内容

利用libuv的源码,创建QT工程,编辑工程文件,实现libuv的源码编译和调试。

libuv版本号:v1.44.1

QT版本号:5.9.9

操作系统:win10/Ubuntu。

创建工程

首先创建QT Console 工程,一路下一步,选择MinGW 32bit的kit。

 在工程的main.cpp所在文件夹中新建libuv文件夹,将下载好的libuv代码中的libuv-v1.44.1\include\和libuv-v1.44.1\src\两个文件夹复制到此文件夹中。

 编辑工程文件

添加依赖文件头文件和源文件路径

在.pro文件中,添加如下代码:

INCLUDEPATH += $$PWD/libuv/include
DEPENDPATH += $$PWD/libuv/include
INCLUDEPATH += $$PWD/libuv/src
DEPENDPATH += $$PWD/libuv/src

 公共头文件和源文件添加

在.pro文件中,将SOURCES 和 HEADERS部分修改为:

SOURCES += \
        libuv/src/fs-poll.c \
        libuv/src/idna.c \
        libuv/src/inet.c \
        libuv/src/random.c \
        libuv/src/strscpy.c \
        libuv/src/threadpool.c \
        libuv/src/timer.c \
        libuv/src/uv-common.c \
        libuv/src/uv-data-getter-setters.c \
        libuv/src/version.c \
        main.cpp

HEADERS += \
    libuv/include/uv.h \
    libuv/include/uv/aix.h \
    libuv/include/uv/bsd.h \
    libuv/include/uv/darwin.h \
    libuv/include/uv/errno.h \
    libuv/include/uv/linux.h \
    libuv/include/uv/os390.h \
    libuv/include/uv/posix.h \
    libuv/include/uv/stdint-msvc2008.h \
    libuv/include/uv/sunos.h \
    libuv/include/uv/threadpool.h \
    libuv/include/uv/tree.h \
    libuv/include/uv/version.h \
    libuv/src/heap-inl.h \
    libuv/src/idna.h \
    libuv/src/queue.h \
    libuv/src/strscpy.h \
    libuv/src/uv-common.h \

 WIN系统依赖库、头文件和源文件添加

WIN系统下,添加预定义 DEFINES += _WIN32_WINNT=0x0602。

WIN系统下,libuv需要7个依赖库,分别为:ws2_32、UserEnv、IPHLPAPI、Psapi、advapi32、User32、Gdi32。

WIN系统下,所需的源码主要集中在“libuv\src\win\”中。添加后如下所示。

win32{
DEFINES += _WIN32_WINNT=0x0602

LIBS += -lws2_32
LIBS += -lUserEnv
LIBS += -lIPHLPAPI
LIBS += -lPsapi
LIBS += -ladvapi32
LIBS += -lUser32
LIBS += -lGdi32

SOURCES += \
        libuv/src/win/async.c \
        libuv/src/win/core.c \
        libuv/src/win/detect-wakeup.c \
        libuv/src/win/dl.c \
        libuv/src/win/error.c \
        libuv/src/win/fs-event.c \
        libuv/src/win/fs.c \
        libuv/src/win/getaddrinfo.c \
        libuv/src/win/getnameinfo.c \
        libuv/src/win/handle.c \
        libuv/src/win/loop-watcher.c \
        libuv/src/win/pipe.c \
        libuv/src/win/poll.c \
        libuv/src/win/process-stdio.c \
        libuv/src/win/process.c \
        libuv/src/win/signal.c \
        libuv/src/win/snprintf.c \
        libuv/src/win/stream.c \
        libuv/src/win/tcp.c \
        libuv/src/win/thread.c \
        libuv/src/win/tty.c \
        libuv/src/win/udp.c \
        libuv/src/win/util.c \
        libuv/src/win/winapi.c \
        libuv/src/win/winsock.c \

HEADERS += \
    libuv/include/uv/win.h \
    libuv/src/win/atomicops-inl.h \
    libuv/src/win/fs-fd-hash-inl.h \
    libuv/src/win/handle-inl.h \
    libuv/src/win/internal.h \
    libuv/src/win/req-inl.h \
    libuv/src/win/stream-inl.h \
    libuv/src/win/winapi.h \
    libuv/src/win/winsock.h
}

 LINUX系统依赖库、头文件和源文件添加

LINUX系统下,添加预定义:
DEFINES += _FILE_OFFSET_BITS=64
DEFINES += _LARGEFILE_SOURCE
DEFINES += _GNU_SOURCE
DEFINES += _POSIX_C_SOURCE=200112。

LINUX系统下,libuv需要pthread依赖库。

LINUX系统下,所需的源码主要集中在“libuv\src\unix\”中,注意并不是此文件夹中所有文件都需要,因为有很多是AIX、MAC、BSD等系统的,常用的Linux系统(如Ubuntu)并不需要。

添加后如下所示。

unix{
LIBS += -lpthread

DEFINES += _FILE_OFFSET_BITS=64
DEFINES += _LARGEFILE_SOURCE
DEFINES += _GNU_SOURCE
DEFINES += _POSIX_C_SOURCE=200112

SOURCES += \
        libuv/src/unix/async.c \
        libuv/src/unix/core.c \
        libuv/src/unix/dl.c \
        libuv/src/unix/fs.c \
        libuv/src/unix/getaddrinfo.c \
        libuv/src/unix/getnameinfo.c \
        libuv/src/unix/loop-watcher.c \
        libuv/src/unix/loop.c \
        libuv/src/unix/pipe.c \
        libuv/src/unix/poll.c \
        libuv/src/unix/process.c \
        libuv/src/unix/random-devurandom.c \
        libuv/src/unix/signal.c \
        libuv/src/unix/stream.c \
        libuv/src/unix/tcp.c \
        libuv/src/unix/thread.c \
        libuv/src/unix/tty.c \
        libuv/src/unix/udp.c \
        libuv/src/unix/proctitle.c \
        libuv/src/unix/linux-core.c \
        libuv/src/unix/linux-inotify.c \
        libuv/src/unix/linux-syscalls.c \
        libuv/src/unix/procfs-exepath.c \
        libuv/src/unix/random-getrandom.c \
        libuv/src/unix/random-sysctl-linux.c \
        libuv/src/unix/epoll.c \

HEADERS += \
    libuv/include/uv/unix.h \
    libuv/src/unix/atomic-ops.h \
    libuv/src/unix/darwin-stub.h \
    libuv/src/unix/internal.h \
    libuv/src/unix/linux-syscalls.h \
    libuv/src/unix/os390-syscalls.h \
    libuv/src/unix/spinlock.h \
}

 编译测试

完成以上编辑后,即可进行工程构建和调试。

(main.cpp中添加)测试代码可用如下:

//#include <QCoreApplication>

#include <uv.h>
#include <stdio.h>

void onConnect(uv_stream_t* server, int status);
void onAlloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
void onRead(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf);
void onWrite(uv_write_t* req, int status);
void onClose(uv_handle_t* handle);

int main() {
    uv_loop_t* loop = uv_default_loop();

    uv_tcp_t server;
    uv_tcp_init(loop, &server);

    struct sockaddr_in address;
    uv_ip4_addr("0.0.0.0", 12345, &address); // 监听本地 12345 端口

    uv_tcp_bind(&server, (struct sockaddr*)&address, 0);
    uv_listen((uv_stream_t*)&server, SOMAXCONN, onConnect);

    printf("Listening on port 12345...\n");

    return uv_run(loop, UV_RUN_DEFAULT);
}

void onConnect(uv_stream_t* server, int status) {
    if (status < 0) {
        fprintf(stderr, "Error: %s\n", uv_strerror(status));
        return;
    }

    uv_loop_t* loop = uv_default_loop();

    uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
    uv_tcp_init(loop, client);

    if (uv_accept(server, (uv_stream_t*)client) == 0) {
        struct sockaddr_in addr;
        int len = sizeof(addr);
        uv_tcp_getpeername(client, (struct sockaddr*)&addr, &len);
        printf("Client connected from %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

        uv_write_t* req = (uv_write_t*)malloc(sizeof(uv_write_t));
        char* message = "Hello, World!";
        uv_buf_t buf = uv_buf_init(message, strlen(message));
        uv_write(req, (uv_stream_t*)client, &buf, 1, onWrite);
    }
    else {
        uv_close((uv_handle_t*)client, onClose);
    }
}

void onAlloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
    buf->base = (char*)malloc(suggested_size);
    buf->len = suggested_size;
}

void onRead(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf) {
    if (nread <= 0) {
        if (nread == UV_EOF) {
            printf("Client disconnected\n");
        }
        else {
            fprintf(stderr, "Error: %s\n", uv_strerror(nread));
        }
        uv_close((uv_handle_t*)client, onClose);
    }
    else {
        printf("Received bytes: %ld\n", nread);
        printf("Received message: %s\n", buf->base);

        // 处理业务逻辑

        free(buf->base);
    }
}

void onWrite(uv_write_t* req, int status) {
    if (status < 0) {
        fprintf(stderr, "Error: %s\n", uv_strerror(status));
        uv_close((uv_handle_t*)req->handle, onClose);
    }
    else {
        uv_read_start((uv_stream_t*)req->handle, onAlloc, onRead);
    }
    free(req);
}

void onClose(uv_handle_t* handle) {
    free(handle);
}

//int main(int argc, char *argv[])
//{
//    QCoreApplication a(argc, argv);

//    return a.exec();
//}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值