C语言从入门到精通-C静态库的生成及使用

静态库

什么是静态库

C静态库(Static Library)是C语言编程中常用的一种库文件形式。与动态库(Dynamic Library)相比,静态库在程序编译时会被完全嵌入到最终的可执行文件中,因此生成的可执行文件不依赖于外部的库文件。这意味着,无论目标系统上是否安装了相应的库,只要编译时包含了静态库,程序就可以正常运行。C静态库(Static Library)是C语言编程中常用的一种库文件形式。与动态库(Dynamic Library)相比,静态库在程序编译时会被完全嵌入到最终的可执行文件中,因此生成的可执行文件不依赖于外部的库文件。这意味着,无论目标系统上是否安装了相应的库,只要编译时包含了静态库,程序就可以正常运行。

CLion生成静态库

使用CLion生成静态库文件。

创建C语言库项目

image-20240429153738838

修改库文件.h名称

image-20240429155312623

编写库中的头文件

#ifndef FFYC_FFYC_H
#define FFYC_FFYC_H


#include <stdio.h>
#include <stdlib.h>
#include<sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>


/**
 * 启动服务器
 * @return
 */
int start_server(int port);
/**
 * 连接服务器
 * @param server_socket
 * @return 返回连接状态
 */
int conn_server(int server_socket);
/**
 * 获取前端返回的数据
 * @param conn_socket 连接状态
 * @param req_buffer 数组存储请求的字符串
 */
void receive_data(int conn_socket, char* req_buffer,int req_buffer_len);
/**
 * 打印字符串数组信息
 * @param array 字符数组
 * @param len 字符数组长度
 */
void print_array(char *array, int len);
/**
 * 获取请求数据
 * @param array
 * @param len
 * @return
 */
char* get_req_data(char *array, int len);
/**
 * 将十六进制转换为十进制
 * @param c 要转换的字符
 * @return 返回十进制数
 */
int hex2dec(char c);
/**
 * 将输入的字符串中的中文翻译为中文正确格式
 * @param url
 */
void url_decode(char url[]);
/**
 * 发送数据到web前端
 * @param conn_socket 连接的socket
 * @param data  传输的数据
 */
void send_data(int conn_socket,char* data);



#endif //FFYC_FFYC_H

编写.c文件

#include "ffyc.h"

char resp_header[] = "HTTP/1.0 200 OK\r\n"
                     "Server: my-AI-X v1.0\r\n"
                     "Content-Type: text/html;charset=utf-8\r\n"
                     "\r\n"
                     "<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8'>"
                     "<title>my ai</title><link rel='shortcut icon' href='data:image/ico;base64,aWNv'/></head></html>";


int start_server(int port) {

    int yes = 1;
    int server_socket =
            socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (server_socket < 0) {

        fprintf(stderr, "[服务器] socket创建失败...\n");
        exit(EXIT_FAILURE);
    }
    printf("[服务器] 创建socket成功^_^\n");

    // 设置 SO_REUSEADDR 选项
    if (setsockopt(server_socket, SOL_SOCKET,
                   SO_REUSEADDR,
                   &yes,
                   sizeof(int)) == -1) {

        fprintf(stderr, "[服务器] 设置socket参数失败...\n");
        exit(1);
    }

    struct sockaddr_in my_sockaddr;
    my_sockaddr.sin_port = htons(port);
    my_sockaddr.sin_family = AF_INET;
    my_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    int bind_ret = bind(server_socket,
                        (struct sockaddr *) &my_sockaddr,
                        sizeof(my_sockaddr));

    if (bind_ret < 0) {
        fprintf(stderr, "[服务器] 绑定端口[%d]失败...\n", port);
        exit(EXIT_FAILURE);
    }
    printf("[服务器] 绑定端口[%d]成功....\n", port);

    int listen_ret = listen(server_socket, 200);

    if (listen_ret < 0) {
        fprintf(stderr, "[服务器] 监听端口[%d]失败...\n", port);
        exit(EXIT_FAILURE);
    }
    printf("[服务器] 监听端口[%d]成功....\n", port);

    return server_socket;

}

int conn_server(int server_socket) {
    //连接服务
    int conn_socket = accept(server_socket, NULL, NULL);

    if (conn_socket < 0) {
        fprintf(stderr, "[服务器] 连接失败....\n");
        exit(EXIT_FAILURE);
    }
    return conn_socket;
}

void receive_data(int conn_socket, char *req_buffer, int req_buffer_len) {
    ssize_t rev_ret = recv(conn_socket, req_buffer, req_buffer_len, 0);

    if (rev_ret < 0) {
        fprintf(stderr, "[服务器] 获取数据失败...\n");
        exit(EXIT_FAILURE);
    }
    if (rev_ret == 0) {
        fprintf(stderr, "[服务器] 超时或对终端主动关闭...\n");
        exit(EXIT_FAILURE);
    }
}

void print_array(char *array, int len) {
    for (int i = 0; i < len; i++) {
        if (array[i] == '\r') {
            continue;
        }
        if (array[i] == 0) break;
        printf("%c", array[i]);
    }
}

char *get_req_data(char *array) {

    unsigned long pos = strcspn(array, "\r\n");
    array[pos] = '\0';
    url_decode(array);
    return array;
}

int hex2dec(char c) {
    if ('0' <= c && c <= '9') {
        return c - '0';
    } else if ('a' <= c && c <= 'f') {
        return c - 'a' + 10;
    } else if ('A' <= c && c <= 'F') {
        return c - 'A' + 10;
    } else {
        return -1;
    }
}


void url_decode(char* url) {

    size_t len = strlen(url);
    int res_len = 0;
    char res[100];

    for (int i = 0; i < len; ++i) {
        char c = url[i];
        if (c != '%') {
            res[res_len++] = c;
        } else {
            char c1 = url[++i];
            char c0 = url[++i];
            int num = hex2dec(c1) * 16 + hex2dec(c0);
            res[res_len++] = (char)num;
        }
    }
    res[res_len] = '\0';
    strcpy(url, res);
}

void send_data(int conn_socket, char *data) {
    send(conn_socket, resp_header, strlen(resp_header), 0);
    send(conn_socket, data, strlen(data), 0);
}

生成静态库

image-20240429164751666

生成静态库文件: libffyc.a

image-20240429165016618

移植库文件到Cygwin64

拷贝xxx.a文件到Cygwin64/lib中

image-20240429165759269

image-20240429170011066

拷贝头文件xxx.h到Cygwin64/usr/include

image-20240429170411336

image-20240429170522197

CLion中应用静态库

cmake_minimum_required(VERSION 3.28)
project(lib_hello C)

set(CMAKE_C_STANDARD 99)

add_executable(lib_hello main.c)

target_link_libraries(${PROJECT_NAME} libffyc.a)

image-20240429171436179

测试使用

#include <stdio.h>
#include "ffyc.h"
int main(void) {

    start_server(9999);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/584349.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BiLSTM-KDE的双向长短期记忆神经网络结合核密度估计多变量回归区间预测(Matlab)

BiLSTM-KDE的双向长短期记忆神经网络结合核密度估计多变量回归区间预测&#xff08;Matlab&#xff09; 目录 BiLSTM-KDE的双向长短期记忆神经网络结合核密度估计多变量回归区间预测&#xff08;Matlab&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.BiLS…

后台架构总结

前言 疫情三年&#xff0c;全国各地的健康码成为了每个人的重要生活组成部分。虽然过去一年&#xff0c;但是回想起来任然历历在目。 今天我就通过当时基于小程序的健康码架构&#xff0c;来给大家讲一下如何基于java&#xff0c;springboot等技术来快速搭建一个后台业务系统…

人工智能分割分类model:nnUnet-paddle

文章目录 神经网络nnUnet和paddle都需要在Ubuntu下进行安装PaddleProject 神经网络 开源来自https://github.com/MIC-DKFZ/nnUNet 自建了仓库&#xff0c;但还不会用 来自 mmsegmentation有空去了解 . MICCAI 2020 也是用到这个网络 paddle上的是不是不能用… nnUnet和pad…

Linux基础IO(下)

目录 1. 缓冲区 1.1 定义 1.2 理解缓冲区 1.2.1 为什么要有缓冲区 1.2.2 缓冲区的工作原理 缓冲区什么时候写入&#xff0c;什么时候刷新&#xff1f; 2. 文件系统 2.1 什么是文件系统&#xff1f; 2.2 为什么要有文件系统&#xff1f; 2.3 认识文件的管理结构 2.…

绩效评估与持续反馈

高绩效团队认识到评论和反馈的商业价值&#xff0c;这是两种关键的绩效管理工具。绩效管理是 2023 年受访者最优先考虑的五项人力资源举措之一&#xff0c;学习和发展是另一项举措&#xff0c;绩效评估和持续反馈最近可能会受到人力资源团队的更多关注。 在这里&#xff0c;我…

每天五分钟玩转深度学习PyTorch:创建pytorch中的零维标量tensor

标量是什么? tensor张量是一个多维数组,零维就是一个点(就是本章的标量),一维就是向量,二维就是一般的矩阵,多维就相当于一个多维的数组,这和 numpy理解是一样的,不同的是Tensor不仅可以在CPU上跑,在GPU上也可以跑。 标量(scalar),只具有数值大小,而没有方向,…

python数据可视化:雷达图

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 python数据可视化&#xff1a; 雷达图 选择题 关于以下代码输出的雷达图中&#xff0c;以下说法正确的是&#xff1f; import numpy as np import matplotlib.pyplot as plt from pylab impor…

深入浅出一文图解Vision Mamba(ViM)

文章目录 引言&#xff1a;Mamba第一章&#xff1a;环境安装1.1安装教程1.2问题总结1.3安装总结 第二章&#xff1a;即插即用模块2.1模块一&#xff1a;Mamba Vision代码&#xff1a;models_mamba.py运行结果 2.2模块二&#xff1a;MambaIR代码&#xff1a;MambaIR运行结果 第三…

IP如何安装SSL证书,实现加密传输

让我们理解一下SSL证书。SSL&#xff08;Secure Sockets Layer&#xff09;证书是一种数字证书&#xff0c;它利用数据加密技术&#xff0c;确保了互联网数据传输的安全。当网站安装了SSL证书后&#xff0c;所有的数据都会经过加密后再传输&#xff0c;这可以防止黑客窃取或篡改…

标贝语音识别技术在金融领域中的应用实例

随着语音识别技术与文本挖掘、自然语言处理等技术的不断融合&#xff0c;智能语音交互技术在金融领域中爆发了出巨大的应用潜力。标贝科技根据自身与金融领域合作的经验为大家梳理出以下几点智能语音识别技术在金融领域中的应用实例。 一、智能柜台服务 语音识别的主要功能就…

如何安全可控的进行跨区域数据交换,提高数据价值?

跨区域数据交换指的是在不同地理位置或不同网络环境下的数据传输和共享。随着数字化转型的加速&#xff0c;企业及组织越来越依赖于数据的流动来优化业务流程、增强决策制定和推动创新。然而&#xff0c;跨区域数据交换也带来了一系列的挑战和风险&#xff0c;主要包括&#xf…

SpringSecurity6配置requestMatchers().permitAll() 无效问题

版本 <spring-boot.version>3.0.2</spring-boot.version> <jjwt.version>0.12.5</jjwt.version>问题描述 题主在写 SpringSecurity6 JWT 做登录认证开发。一路跟着教程叭叭的敲。等到接口验证的时候&#xff0c;发现我的登录接口虽然在SecurityConf…

maven多模块创建-安装配置

1、前提 许久没有写文章了&#xff0c;荒废了2年多的时间&#xff0c;在整理的时候&#xff0c;发现Maven还差一篇安装配置的文章&#xff0c;现在开始提笔完善它&#xff0c;参考&#xff1a;https://blog.csdn.net/m0_72803119/article/details/134634164。 —写于2024年4月…

有什么好用的足球数据分析工具,可以生成可靠的投注策略?

在寻找好用的足球数据分析工具以生成可靠的投注策略时&#xff0c;有几个值得考虑的选项。以下是一些工具和建议&#xff1a; 乐彩数据分析&#xff1a;这款工具以其精准的预测和高达70%以上的准确率而受到赞誉。它利用大数据算法进行预测&#xff0c;相比个人预测更加准确。此…

五一假期终于到了!是时候偷偷发力了!——早读(逆天打工人爬取热门微信文章解读)

狗子&#xff0c;别偷跑&#xff01;给我好好休息 引言Python 代码第一篇 洞见 无论在哪儿上班&#xff0c;冷漠是你最后的底线第二篇 人民日报要闻社会政策 结尾 我们不应该把休息 仅仅看作身体的需求 而敷衍了事 我们要把休息 看成一种机遇 停下工作 好好休息 并没有妨碍创造…

【数据结构】合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 Definition for singly-linked list.struct ListNode {int val;struct ListNode *next;};typedef struct ListNode ListNode; struct ListNode* mergeTwoLists(struct Lis…

LT6911UXE HDMI 2.0 至双端口 MIPI DSI/CSI,带音频 龙迅方案

1. 描述LT6911UXE 是一款高性能 HDMI2.0 至 MIPI DSI/CSI 转换器&#xff0c;适用于 VR、智能手机和显示应用。HDMI2.0 输入支持高达 6Gbps 的数据速率&#xff0c;可为4k60Hz视频提供足够的带宽。此外&#xff0c;数据解密还支持 HDCP2.3。对于 MIPI DSI / CSI 输出&#xff0…

rtl8188ftv debian linux 多架构移植方法

5 块包邮&#xff0c;挂到 x86_64 debian 12 虚拟机&#xff0c;实测下载能到 22Mbps&#xff0c;也可能就2Mbps&#xff0c;上传能到 40Mbps 关键词&#xff1a; rtl8xxxu、rtl8xxxu.ko、rtl8xxxu_8188f.c、mac80211.h、cfg80211.ko、sudo modinfo rtl8xxxu.ko | grep depen…

【Qt】error LNK2001: 无法解析的外部符号

参考&#xff1a;Qt/VS LNK2019/LNK2001&#xff1a;无法解析的外部符号_qt lnk2001无法解析的外部符号-CSDN博客 微软官方报错文档-链接器工具错误 LNK2019 __declspec error LNK2001: 无法解析的外部符号 "__declspec(dllimport) 原因 以这种为前缀的基本上跟库相关…

用Scrapy编写第一个入门项目(基础四件套:spider,pipeline,setting,items)

简介&#xff1a;scrapy是一个用于爬取网页并提取数据的应用框架&#xff0c;也可用于提取API数据 写在前面&#xff1a;只想看scrapy的童鞋子请跳过5-7直接step8&#xff09; step5&#xff0c;6是xpath和css入门&#xff0c;用于提取数据&#xff1b; step7是文件储存方式&…