目录

组件化的意义

头文件及源代码

头文件:

源文件:

 提取头文件及源文件

第一步:先用文件资源管理器打开文件夹:

第二步:将头文件及源代码复制到桌面:

封装静态库

 第一步:创建一个静态库项目:

 第二步:将头文件与源代码添加到项目文件中:

第三步:处理代码:

 第四步:生成:

 第五步:找到库:

第六步:使用:

 封装动态链接库

第一步:添加一个动态链接库项目:

 第二步:将头文件和源文件添加到项目中:

 第三步:处理代码:

 第四步:生成:

第五步:找到库:

第六步:使用:

静态库和动态链接库的区别


组件化的意义

组件化可以带来以下几个方面的意义:

  1. 可重用性:将应用程序拆分成多个独立的组件,可以使得这些组件可被复用于不同的应用程序中。
  2. 维护性:对于功能和代码变更,只需要修改对应的组件而不是整个应用程序,可以降低维护成本。
  3. 模块化开发:将应用程序拆分成多个独立的组件,可以使得多个团队并行进行开发,提高开发效率。
  4. 测试性:将应用程序拆分成多个独立的组件,可以针对每个组件进行单元测试,在保障质量的同时提高测试覆盖率。

头文件及源代码

以封装string有关的组件为例

头文件:

#pragma once
#include <string.h>
#include <stdlib.h>
/*
功能:判断一个字符串中是否包含另一个字符串
参数:str:目标字符长串
	 substr:被查找的短字符串
返回:0 不包含 1包含
简例:int a = contains("Hello ,how are you","are");
返回 1;
*/ 
int contains(const char* str,const char *substr) ;
 
/*
功能:判断一个字符串的开头是否与另一个字符串相同
参数:str 目标字符串 substr被比较字符串
返回:0 否 1 是
简例:int a =startsWith("Hello ,how are you","Hello");
返回值:1
*/
int startsWith(const char* str,const char *substr);
 
/*
功能:判断一个字符串的结尾是否与另一个字符串相同
参数:str 目标字符串 substr被比较字符串
返回:0 否 1 是
简例:int a =endsWith("Hello ,how are you","are");
返回值:1
*/
int endsWith(const char* str,const char *substr);
 
/*
功能:从一个字符串前面寻找另一个字符串首次出现的下标
参数:str目标字符串,substr寻找字符串
返回:下标位置
简例:int a= strIndexOf("how are you","are");
返回值:4
*/
int strIndexOf(const char* str,const char* substr) ;
 
/*
功能:在一个字符串str前面开始寻找字符c首次出现的下标
参数:str目标字符串,c 被寻找的字符
返回:下标位置
简例:int a= charIndexOf("how are you",'w');
返回值:2
*/
int charIndexOf(const char* str,char c) ;
 
/*
功能:从一个字符串尾部开始寻找另一个字符串首次出现的下标
参数:str目标字符串,substr寻找字符串
返回:下标位置
简例:int a= strLastIndexOf("how do you do","do");
返回值:11
*/
int strLastIndexOf(const char* str,const char* substr) ;
 
/*
功能:在一个字符串str尾部开始寻找字符c首次出现的下标
参数:str目标字符串,c 被寻找的字符
返回:下标位置
简例:int a= charLastIndexOf("how are you",'o');
返回值:9
*/
int charLastIndexOf(const char* str,char c) ;
 
/*
功能:判断一个字符串是否空串
参数:str被检测的字符串
返回:0 不是 1 是
简例:int a = isEmpty("");
返回值 1 
*/
int isEmpty(const char* str) ;
 
/*
功能:去掉字符串中的所有空格
参数:str 需要去掉空格的字符串
返回:处理后的str
简例:
char s[] = "  how are you  ";
trimAll(s)
返回值:howareyou
*/
char* trimAll(char* str) ;
 
/*
功能:只去掉字符串左侧的所有空格
参数:str: 需要去掉左侧空格的字符串
返回:处理后的str
简例:
char s[] = "  how are you  ";
leftTrim(s)
返回值:how are you  |
*/
char* leftTrim(char* str) ;
 
/*
功能:只去掉字符串右侧的所有空格
参数:str: 需要去掉右侧空格的字符串
返回:处理后的str
简例:
char s[] = "  how are you  ";
rightTrim(s)
返回值:  how are you|
*/
char* rightTrim(char* str) ;
 
/*
功能:把字符串的字母全部转换成大写 
参数:str被变大写的字符串
返回:处理后的str
简例:
char s[] = "how are you";
toUpperCase(s);
返回值: HOW ARE YOU
*/
char* toUpperCase(char* str ) ;
 
/*
功能:把字符串的字母全部转换成小写 
参数:str被变小写的字符串
返回:处理后的str
简例:
char s[] = "IEEE1394";
toUpperCase(s);
返回值: ieee1394
*/
char* toLowerCase(char* str ) ;
 
/*
功能:忽略大小写字母,比较两个字符串的大小
参数:str1 str2 两个比较的字符串
返回:1 大于关系 0 等于关系 -1小于关系
简例:int a=strcmpIgnorecase("Are","are");
返回值:0
*/
int strcmpIgnorecase(const char* str1,const char *str2) ;
 
/*
功能:对一个字符串进行翻转
参数:str被翻转的字符串
返回:翻转处理后的str
简例:char s[] ="12345";
返回值:54321
*/
char* reserveStr(char *str);
 
/*
功能:把一个s字符串重复连接n次后存放到d字符串
参数:d最终结果字符串,s被重复的字符串 n 重复的次数
返回:d最终结果字符串
简例:char a[50];
repeat(a,"sorry!",3);
返回值:sorry!sorry!sorry!
*/
char* repeat(char* d,const char *s ,int n) ;
 
/*
功能:把一个长串中的一段字符串复制到另一个字符串。
参数:s 长串 from从 to到(但不包括) d存放位置
返回:d字符串的结果
简例:char d[20];
substr("hello world",2,5,d);
返回值:llo
*/
char* substr(const char* s,int from ,int to,char * d) ;
 
/*
功能:把sub字符串插入到str的指定下标位置
参数:str目标字符串 sub被插入的子串 index 插入点下标。
返回:处理后的str
简例:
char s[50]="how you";
insert(s,"are ",3);
返回值:how are you
*/
char* insert(char* str,const char *sub,int index) ;
 
/*
功能:把字符串中指定下标的字符删除掉
参数:str目标字符串,index 被删除下标
返回:处理后的str
简例:char s[]="how you";
	deleteCharAt(s,1);
返回值:hw you	
*/
char* deleteCharAt(char* str,int index) ;
 
/*
功能:把str字符串中的一段字符删除掉
参数:str被删除的字符串 from删除开始点 to 结束点(但不包括)
返回:处理后的str
简例:
char s[]="how you";
deleteSubstr(s,0,4);
返回值:you
*/
char* deleteSubstr(char* str,int from ,int to) ;
 
/*
功能:把字符串str的一小段字符替换成另一个字符串sub
参数:str目标字符串 from起始点,to结束点(但不包括) sub替换的内容
返回:处理后的str
简例:
char s[50]="how is you";
replace(s,4,6,"are");
返回值:how are you
*/
char* replace(char* str,int from ,int to,const char * sub); 
 
/*
功能:把字符串str中的某些部分替换成另外的字符串
参数:str目标字符串 oldsub原来的内容 newsub 新的内容
返回:处理后的str
简例:
char s[50]="how did you did";
replaceAll(s,"did","do");
返回值:how do you do
*/
char* replaceAll(char* str,const char *oldsub,const char* newsub) ;

源文件:

#include"string_pro.h"
/*
功能:判断一个字符串中是否包含另一个字符串
参数:str:目标字符长串
	 substr:被查找的短字符串
返回:0 不包含 1包含
简例:int a = contains("Hello ,how are you","are");
返回 1;
*/
int contains(const char* str, const char* substr)
{
	return strstr(str, substr) != NULL;
}

/*
功能:判断一个字符串的开头是否与另一个字符串相同
参数:str 目标字符串 substr被比较字符串
返回:0 否 1 是
简例:int a =startsWith("Hello ,how are you","Hello");
返回值:1
*/
int startsWith(const char* str, const char* substr)
{
	return strstr(str, substr) == str;
}

/*
功能:判断一个字符串的结尾是否与另一个字符串相同
参数:str 目标字符串 substr被比较字符串
返回:0 否 1 是
简例:int a =endsWith("Hello ,how are you","are");
返回值:1
*/
int endsWith(const char* str, const char* substr)
{
	//1
	//return strstr(str + strlen(str) - strlen(substr), substr) != NULL;
	//2
	return strcmp(str + strlen(str) - strlen(substr), substr) == 0;
	//3
	//return strstr(str, substr) == str + strlen(str) - strlen(substr);
}

/*
功能:从一个字符串前面寻找另一个字符串首次出现的下标
参数:str目标字符串,substr寻找字符串
返回:下标位置
简例:int a= strIndexOf("how are you","are");
返回值:4
*/
int strIndexOf(const char* str, const char* substr)
{
	return strstr(str, substr) - str;
}

/*
功能:在一个字符串str前面开始寻找字符c首次出现的下标
参数:str目标字符串,c 被寻找的字符
返回:下标位置
简例:int a= charIndexOf("how are you",'w');
返回值:2
*/
int charIndexOf(const char* str, char c)
{
	//1
	/*for (int i = 0; str[i]; i++)
	{
		if (str[i] == c)
		{
			return i;
		}
	}
	return -1;*/
	char substr[2] = { c };
	return strIndexOf(str, substr);
}

/*
功能:从一个字符串尾部开始寻找另一个字符串首次出现的下标
参数:str目标字符串,substr寻找字符串
返回:下标位置
简例:int a= strLastIndexOf("how do you do","do");
返回值:11
*/
int strLastIndexOf(const char* str, const char* substr)
{
	const char* p = str;
	const char* q = NULL;
	do
	{
		p = strstr(p, substr);
		if (p != NULL)
		{
			q = p;
			p++;
		}
	} while (p!=NULL);
	return q != NULL ? q - str : -1;
}

/*
功能:在一个字符串str尾部开始寻找字符c首次出现的下标
参数:str目标字符串,c 被寻找的字符
返回:下标位置
简例:int a= charLastIndexOf("how are you",'o');
返回值:9
*/
int charLastIndexOf(const char* str, char c)
{
	char t[2] = { c };
	return strLastIndexOf(str, t);
}

/*
功能:判断一个字符串是否空串
参数:str被检测的字符串
返回:0 不是 1 是
简例:int a = isEmpty("");
返回值 1
*/
int isEmpty(const char* str)
{
	return *str == '\0';//strlen(str)==0;
}

/*
功能:去掉字符串中的所有空格
参数:str 需要去掉空格的字符串
返回:处理后的str
简例:
char s[] = "  how are you  ";
trimAll(s)
返回值:howareyou
*/
char* trimAll(char* str)
{
	char* p = str;
	int len = 0;//非空格的长度
	while (*p)
	{
		if (*p != ' ')
		{
			str[len++] = *p;
		}
		p++;
	}
	str[len] = '\0';
	return str;
}

/*
功能:只去掉字符串左侧的所有空格
参数:str: 需要去掉左侧空格的字符串
返回:处理后的str
简例:
char s[] = "  how are you  ";
leftTrim(s)
返回值:how are you  |
*/
char* leftTrim(char* str)
{
	char* p = str;
	while (*p == ' ')
		p++;
	return strcpy(str, p);
}

/*
功能:只去掉字符串右侧的所有空格
参数:str: 需要去掉右侧空格的字符串
返回:处理后的str
简例:
char s[] = "  how are you  ";
rightTrim(s)
返回值:  how are you|
*/
char* rightTrim(char* str)
{
	char* p = str + strlen(str) - 1;
	while (*p == ' ')
		p--;
	*(p + 1) = '\0';
	return str;

}

/*
功能:把字符串的字母全部转换成大写
参数:str被变大写的字符串
返回:处理后的str
简例:
char s[] = "how are you";
toUpperCase(s);
返回值: HOW ARE YOU
*/
char* toUpperCase(char* str)
{
	char* p = str;
	while (*p)
	{
		if (*p >= 'a' && *p <= 'z')
		{
			*p -= 32;
		}
		p++;
	}
	return str;
}

/*
功能:把字符串的字母全部转换成小写
参数:str被变小写的字符串
返回:处理后的str
简例:
char s[] = "IEEE1394";
toUpperCase(s);
返回值: ieee1394
*/
char* toLowerCase(char* str)
{
	for (int i = 0,len= strlen(str); i <len ; i++)
	{
		if (str[i] >= 'A' && str[i] <= 'Z')
		{
			str[i] += 32;
		}
	}
	return str;
}

/*
功能:忽略大小写字母,比较两个字符串的大小
参数:str1 str2 两个比较的字符串
返回:1 大于关系 0 等于关系 -1小于关系
简例:int a=strcmpIgnorecase("Are","are");
返回值:0
*/
int strcmpIgnorecase(const char* str1, const char* str2)
{
	//临时的数组
	//char tmpStr1[strlen(str1)+1];
	char* p_str1 = (char*)malloc(sizeof(char) * (strlen(str1) + 1));
	char* p_str2 = (char*)malloc(sizeof(char) * (strlen(str2) + 1));
	/*strcpy(p_str1, str1);
	strcpy(p_str2, str2);*/
	if (p_str1 && p_str2)
	{
		memcpy(p_str1, str1, strlen(str1) + 1);
		memcpy(p_str2, str2, strlen(str2) + 1);
		toLowerCase(p_str1);
		toLowerCase(p_str2);
		int r = strcmp(p_str1, p_str2);
		free(p_str1);
		free(p_str2);
		return r;
	}
	return 0;
}

/*
功能:对一个字符串进行翻转
参数:str被翻转的字符串
返回:翻转处理后的str
简例:char s[] ="12345";
返回值:54321
*/
char* reserveStr(char* str)
{
	char t;
	for (char* p = str, *q = str + strlen(str) - 1; p < q; p++, q--)
	{
		t = *q;
		*q = *p;
		*p = t;
	}
	return str;
}

/*
功能:把一个s字符串重复连接n次后存放到d字符串
参数:d最终结果字符串,s被重复的字符串 n 重复的次数
返回:d最终结果字符串
简例:char a[50];
repeat(a,"sorry!",3);
返回值:sorry!sorry!sorry!
*/
char* repeat(char* d, const char* s, int n)
{
	d[0] = '\0';
	for (int i = 0; i < n; i++)
	{
		strcat(d, s);
	}
	return d;
}

/*
功能:把一个长串中的一段字符串复制到另一个字符串。
参数:s 长串 from从 to到(但不包括) d存放位置
返回:d字符串的结果
简例:char d[20];
substr("hello world",2,5,d);
返回值:llo
*/
char* substr(const char* s, int from, int to, char* d)
{
	//1
	/*int len;
	for (len = 0; len < to - from; len++)
	{
		d[len] = s[from + len];
	}
	d[len] = '\0';*/
	//2
	strncpy(d, s + from, to - from);
	//memcpy(d, s + from, to - from);
	d[to - from] = '\0';
	return d;
}

/*
功能:把sub字符串插入到str的指定下标位置
参数:str目标字符串 sub被插入的子串 index 插入点下标。
返回:处理后的str
简例:
char s[50]="how you";
insert(s,"are ",4);
返回值:how are you
*/
char* insert(char* str, const char* sub, int index)
{
	char* p = str + index;
	char* temp = (char*)malloc(sizeof(char) * (strlen(p)+1));
	if (temp)
	{
		strcpy(temp, p);
		*p = '\0';
		strcat(str, sub);
		strcat(str, temp);
		free(temp);
	}

	return str;
}

/*
功能:把字符串中指定下标的字符删除掉
参数:str目标字符串,index 被删除下标
返回:处理后的str
简例:char s[]="how you";
	deleteCharAt(s,1);
返回值:hw you
*/
char* deleteCharAt(char* str, int index)
{
	return strcpy(str + index, str + index + 1);
}

/*
功能:把str字符串中的一段字符删除掉
参数:str被删除的字符串 from删除开始点 to 结束点(但不包括)
返回:处理后的str
简例:
char s[]="how you";
deleteSubstr(s,0,4);
返回值:you
*/
char* deleteSubstr(char* str, int from, int to)
{
	return strcpy(str + from, str + to);
}

/*
功能:把字符串str的一小段字符替换成另一个字符串sub
参数:str目标字符串 from起始点,to结束点(但不包括) sub替换的内容
返回:处理后的str
简例:
char s[50]="how is you";
replace(s,4,6,"are");
返回值:how are you
*/
char* replace(char* str, int from, int to, const char* sub)
{
	deleteSubstr(str, from, to);
	return insert(str, sub, from);
}

/*
功能:把字符串str中的某些部分替换成另外的字符串
参数:str目标字符串 oldsub原来的内容 newsub 新的内容
返回:处理后的str
简例:
char s[50]="how did you did";
replaceAll(s,"did","do");
返回值:how do you do
*/
char* replaceAll(char* str, const char* oldsub, const char* newsub)
{
	char* p = str;
	int from, to;
	do
	{
		p = strstr(p, oldsub);
		if (p)
		{
			from = p - str;
			to = from + strlen(oldsub);
			replace(str, from, to, newsub);
		}
	} while (p != NULL);
	return str;
}

 提取头文件及源文件

第一步:先用文件资源管理器打开文件夹:

将c语言lib封装为为python c代码封装成库_开发语言

第二步:将头文件及源代码复制到桌面:

将c语言lib封装为为python c代码封装成库_开发语言_02

封装静态库

 第一步:创建一个静态库项目:

将c语言lib封装为为python c代码封装成库_头文件_03

 

将c语言lib封装为为python c代码封装成库_c语言_04

 确定好项目名称和解决方案名称还有文件位置之后创建即可

将c语言lib封装为为python c代码封装成库_将c语言lib封装为为python_05

 第二步:将头文件与源代码添加到项目文件中:

将c语言lib封装为为python c代码封装成库_字符串_06

 将头文件添加到头文件,源代码添加到源文件:

将c语言lib封装为为python c代码封装成库_头文件_07

第三步:处理代码:

 在源代码的第一句加上#include "pch.h" (一定要是第一句)

将c语言lib封装为为python c代码封装成库_开发语言_08

 在pch.h头文件的第一句关闭安全警告

将c语言lib封装为为python c代码封装成库_字符串_09

 第四步:生成:

将c语言lib封装为为python c代码封装成库_c语言_10

将c语言lib封装为为python c代码封装成库_字符串_11

 第五步:找到库:

打开解决方案所在文件夹

将c语言lib封装为为python c代码封装成库_将c语言lib封装为为python_12

在Debug中找到库

将c语言lib封装为为python c代码封装成库_头文件_13

 

将c语言lib封装为为python c代码封装成库_将c语言lib封装为为python_14

 可以将库先复制到桌面上

第六步:使用:

在解决方案中创建一个空项目

将c语言lib封装为为python c代码封装成库_头文件_15

 命名为测试string组件

将c语言lib封装为为python c代码封装成库_开发语言_16

 将库与头文件粘贴到项目所在文件夹中

将c语言lib封装为为python c代码封装成库_头文件_17

 找到库的相对路径

将c语言lib封装为为python c代码封装成库_头文件_18

 写入头文件并加载组件

将c语言lib封装为为python c代码封装成库_头文件_19

测试组件

char str[] = "how are you hahaha";
	printf("hello %s\n",toUpperCase(str));

 

将c语言lib封装为为python c代码封装成库_字符串_20

 封装动态链接库

第一步:添加一个动态链接库项目:

将c语言lib封装为为python c代码封装成库_头文件_21

 命名为DllStringpro并创建

将c语言lib封装为为python c代码封装成库_字符串_22

 第二步:将头文件和源文件添加到项目中:

将c语言lib封装为为python c代码封装成库_将c语言lib封装为为python_23

 在头文件中加入头文件,源文件中加入源代码

将c语言lib封装为为python c代码封装成库_c语言_24

 第三步:处理代码:

在源代码的第一句加上#include "pch.h"

将c语言lib封装为为python c代码封装成库_头文件_25

 在pch.h头文件中关闭安全警告

将c语言lib封装为为python c代码封装成库_头文件_26

 在string_pro.h头文件中的每个功能函数前面加上_declspec(dllexport)

将c语言lib封装为为python c代码封装成库_将c语言lib封装为为python_27

 第四步:生成:

将c语言lib封装为为python c代码封装成库_将c语言lib封装为为python_28

将c语言lib封装为为python c代码封装成库_开发语言_29

 第五步:找到库:

在解决方案文件中的Debug文件中找到 

将c语言lib封装为为python c代码封装成库_开发语言_30

可以先拷贝到桌面

 

将c语言lib封装为为python c代码封装成库_将c语言lib封装为为python_31

 .h是开发用的,.lib是引导调用的,.dll是真正的程序

第六步:使用:

将.lib文件加入到测试项目中,可以观察到动态链接库的lib比静态库的lib要小很多

由于头文件已经在测试静态库是添加过了,就不用二次添加了

将c语言lib封装为为python c代码封装成库_将c语言lib封装为为python_32

 加载动态组件:

将c语言lib封装为为python c代码封装成库_c语言_33

发现现在程序可以执行

将c语言lib封装为为python c代码封装成库_将c语言lib封装为为python_34

原因是在解决方案中有dll,然后exe通过lib来调用dll 

将c语言lib封装为为python c代码封装成库_头文件_35

 dll是在项目外的,但是一定要跟exe在同一路径

静态库和动态链接库的区别

将c语言lib封装为为python c代码封装成库_c语言_36

 静态库需要放到项目中,他会跟随项目一同打包为exe文件,所以如果exe用到的组件较多,那么他的文件体积会很大,并且每个程序的代码区都会有一份静态库,会造成空间浪费。他还不易更新,在更新时要将所有程序都更新一遍,他的优点就是移植方便。动态链接库是独立在exe外边的,它属于资源共享,谁想用谁就调用它即可,并且升级也很简单,只要更新自己就行,因为不需要打包在exe文件内,所以文件体积也会较小。