静态库
什么是静态库
C静态库(Static Library)是C语言编程中常用的一种库文件形式。与动态库(Dynamic Library)相比,静态库在程序编译时会被完全嵌入到最终的可执行文件中,因此生成的可执行文件不依赖于外部的库文件。这意味着,无论目标系统上是否安装了相应的库,只要编译时包含了静态库,程序就可以正常运行。C静态库(Static Library)是C语言编程中常用的一种库文件形式。与动态库(Dynamic Library)相比,静态库在程序编译时会被完全嵌入到最终的可执行文件中,因此生成的可执行文件不依赖于外部的库文件。这意味着,无论目标系统上是否安装了相应的库,只要编译时包含了静态库,程序就可以正常运行。
CLion生成静态库
使用CLion生成静态库文件。
创建C语言库项目
修改库文件.h名称
编写库中的头文件
#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);
}
生成静态库
生成静态库文件: libffyc.a
移植库文件到Cygwin64
拷贝xxx.a文件到Cygwin64/lib中
拷贝头文件xxx.h到Cygwin64/usr/include
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)
测试使用
#include <stdio.h>
#include "ffyc.h"
int main(void) {
start_server(9999);
return 0;
}