ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

c语言模块化开发(GCC编译实例)

c语言模块化开发(GCC编译实例) 前提c语言编译步骤参考一个*.c文件是如何一步步成为*.exe的?参见C语言真正的编译过程window下GCC(minGW)的安装参见MinGW下载安装GCC常见命令参见Linux GCC常用命令本人理解的c语言编译过程、中间文件、常用命令本次实验环境window7、minGW实验代码https://download.csdn.net/download/u010476739/10800828实验一、编译单个文件代码 test.c#include stdio.h #include stdlib.h int main() { printf(hello\n); system(pause); }gcc命令(gcc test.c -o test.exe -save-temps)编译结果双击执行test.exe实验二、编译多个文件目录sub.hsub.cmain.c代码sub.h#ifndef MY_MATH #define MY_MATH int add(int,int); int sub(int,int); #endif代码sub.cint add(int x,int y) { return xy; } int sub(int x,int y) { return x-y; }代码main.c#include stdio.h #include stdlib.h #include sub.h int main() { int a5; int b2; printf(add(a,b)%d\n,add(a,b)); printf(sub(a,b)%d\n,sub(a,b)); system(pause); return 0; }执行命令gcc sub.c main.c -o test.exe实验三、模块化编程文件目录结构:headerm1.hm2.hmod1m1.cmod2m2.cmain.c代码:m1.h#ifndef M1 #define M1 int add(int,int); #endifm2.h#ifndef M2 #define M2 int sub(int,int); #endifm1.cint add(int x,int y) { return xy; }m2.cint sub(int x,int y) { return x-y; }main.c#include stdio.h #include stdlib.h #include header/m1.h #include header/m2.h int main() { int a5,b3; printf(add(a,b)%d\n,add(a,b)); printf(sub(a,b)%d\n,sub(a,b)); system(pause); }编译方案一、各自单独编译,最后链接成exe程序1.编译模块mod1(仅需要m1.c)cd mod1gcc -c m1.c -o m1.obj2.编译模块mod2(仅需要m2.c)cd mod2gcc -c m2.c -o m2.obj3.编译主模块maincd ..gcc -c main.c -o main.obj4.将main.obj,m1.obj,m2.obj链接到一起gcc main.obj mod1/m1.obj mod2/m2.obj -o test.exe编译方案二、直接编译直接将这些文件编译成exe可执行程序gcc main.c mod1/m1.c mod2/m2.c -o test.exe实验四、gcc命令选项文件目录结构:headerm1.hm2.hmod1m1.cmod2m2.cmain.c代码:m1.h#ifndef M1 #define M1 int add(int,int); #endifm2.h#ifndef M2 #define M2 int sub(int,int); #endifm1.cint add(int x,int y) { return xy; }m2.cint sub(int x,int y) { return x-y; }main.c#include stdio.h #include stdlib.h #include m1.h #include m2.h int main() { int a5,b3; printf(add(a,b)%d\n,add(a,b)); printf(sub(a,b)%d\n,sub(a,b)); system(pause); }1.编译主模块main.c 并指定include查找的路径gcc -I ./header -c main.c -o main.obj2.编译模块m1.cgcc -c mod1/m1.c -o mod1.obj3.编译模块m2.cgcc -c mod2/m2.c -o mod2.obj4.将编译的结果链接为一个exe程序gcc main.obj mod1/m1.obj mod2/m2.obj -o test.exe实验五、gcc生成动态库dll文件目录结构:myfuncmyfunc.hmyfunc.cmain.c代码:myfunc.h#ifndef MYFUNC #define MYFUNC int add(int,int); #endifmyfunc.cint add(int x,int y) { return xy; }main.c#include stdio.h #include stdlib.h int add(int,int); int main() { int a10,b2; printf(add(a,b)%d\n,add(a,b)); system(pause); }编译思路:首先将myfunc.c编译为动态库文件myfunc.dll,myfunc.h文件可以供外面调用然后编译main.c文件并使用myfunc.dll链接为main.exe可执行文件将myfunc.dll拷贝到main.exe同一个目录下,双击main.exe可查看效果1.编译myfunc.c文件为动态库myfunc.dllcd myfuncgcc myfunc.c -shared -o myfunc.dll2.编译main.c文件并链接为main.exe可执行程序cd ..gcc main.c myfunc/myfunc.dll -o main.exe3.将myfunc/myfunc.dll文件拷贝至与main.exe同目录后双击运行main.exe实验六、gcc生成静态库lib文件目录结构:staticmodmod.hmod.cmain.c代码:mod.h#ifndef MOD #define MOD int add(int,int); #endifmod.cint add(int x,int y) { return xy; }main.c#include stdio.h #include stdlib.h int add(int,int); int main() { int a1,b6; printf(add(a,b)%d\n,add(a,b)); system(pause); return 0; }实现思路:首先将mod.c编译为静态链接库 mod.lib(仅mod.c就可以了)然后编译main.c生成main.exe,生成后的main.exe可单独运行1.将mod.c编译生成静态链接库cd staticmodgcc -c mod.c -o mod.obj使用ar将obj文件打包成.lib文件ar -crv mod.lib mod.obj2.编译main.c生成main.exe可执行程序cd ..gcc main.c staticmod/mod.lib -o main.exe双击生成后的main.exe即可运行实验七、gcc生成的多个动态库相互引用目录结构:mod1m1.cm1.hmod2m2.hm2.cmod3m3.hm3.cmain.c代码:m1.h#ifndef MOD1 #define MOD1 int func1(x,y); #endifm1.cint func1(int x,int y) { return xy; }m2.h#ifndef MOD2 #define MOD2 int func2(int,int); #endifm2.cint func1(int,int); int func2(int x,int y) { int resfunc1(x,y); resres2; return res; }m3.h#ifdefine MOD3 #define MOD3 int func3(int,int); #endifm3.cint func2(int,int); int func3(int x,int y) { int resfunc2(x,y); res3; return res; }main.c#include stdio.h #include stdlib.h int func3(int,int); int main() { int a10,b2; printf(func3(a,b)%d\n,func3(a,b)); system(pause); return 0; }实现思路:首先将m1.c编译为动态库m1.dll,m2.c编译为m2.dll,m3.c编译为m3.dll然后将main.c编译并链接为main.exe,将m1.dll,m2.dll,m3.dll拷贝到main.exe同目录下,然后双击main.exe运行可以看到效果1.将m1.c编译为m1.dllcd mod1gcc -shared m1.c -o m1.dll2.将m2.c编译为m2.dllcd ../mod2gcc -shared m2.c ../mod1/m1.dll -o m2.dll3.将m3.c编译为m3.dllcd ../mod3gcc -shared m3.c ../mod2/m2.dll -o m3.dll4.将main.c编译为main.execd ..gcc main.c mod3/m3.dll -o main.exe将m1.dll,m2.dll,m3.dll拷贝到main.exe同目录下,双击main.exe即可看到效果实验八、gcc生成的多个静态库相互引用mod1是一个静态库,mod2是一个静态库引用了mod1,主模块main引用了mod2目录结构:mod1m1.hm1.cmod2m2.hm2.cmain.c代码:m1.h#ifndef MOD1 #define MOD1 int func1(int,int); #endifm1.cint func1(int x,int y) { return xy; }m2.h#ifndef MOD2 #define MOD2 int func2(int,int); #endifm2.cint func1(int,int); int func2(int x,int y) { int resfunc1(x,y); res3; return res; }main.c#include stdio.h #include stdlib.h int func2(int,int); int main() { int a10,b5; printf(func2(a,b)%d\n,func2(a,b)); system(pause); }实现思路:首先将mod1编译成obj文件,可以考虑继续打包成lib文件然后将mod2编译成obj文件,然后将mod1的obj文件和mod2的obj文件一块打包成m2.lib文件最后编译main.c引用m2.lib文件即可1.将mod1编译成obj文件cd mod1gcc -c m1.c -o m1.obj下一条命令可选ar -crv m1.lib m1.obj2.将mod2编译成obj文件cd ../mod2gcc -c m2.c -o m2.obj将m1.obj和m2.obj联合打包成m2.lib文件ar -crv m2.lib ../mod1/m1.obj m2.obj3.编译main.ccd ..gcc main.c mod2/m2.lib -o main.exe双击运行main.exe即可看到效果实验九、gcc生成exe同时引用动态库和静态库主模块同时引用静态库和动态库:mod1是一个静态库,mod2是一个动态库,主模块main引用了mod1和mod2目录结构:mod1m1.hm1.cmod2m2.hm2.cmain.c代码:m1.h#ifndef MOD1 #define MOD1 int func1(int,int); #endifm1.cint func1(int x,int y) { return xy; }m2.h#ifndef MOD2 #define MOD2 int func2(int,int); #endifm2.cint func2(int x,int y) { return x-y; }main.c#include stdio.h #include stdlib.h int func1(int,int); int func2(int,int); int main() { int a10,b5; printf(func1(a,b)%d\n,func1(a,b)); printf(func2(a,b)%d\n,func2(a,b)); system(pause); }实现思路:首先将mod1编译成obj并继续打包成lib文件,将mod2直接编译为dll文件然后编译main.c引用m1.lib和m2.dll文件即可,将m2.dll拷贝到main.exe同目录双击运行即可1.将mod1编译成obj文件并打包成lib文件cd mod1gcc -c m1.c -o m1.objar -crv m1.lib m1.obj2.将mod2编译成dll文件cd ../mod2gcc -shared m2.c -o m2.all3.编译main.ccd ..gcc main.c mod1/m1.lib mod2/m2.dll -o main.exe将m2.dll拷贝到main.exe同目录,双击main.exe运行即可看到效果实验十、gcc静态库引用动态库mod1是动态库,mod2是静态库并且引用mod1,,主模块引用mod2目录结构:mod1m1.hm1.cmod2m2.hm2.cmain.c代码:m1.h#ifndef MOD1 #define MOD1 int func1(int,int); #endifm1.cint func1(int x,int y) { return xy; }m2.h#ifndef MOD2 #define MOD2 int func2(int,int); #endifm2.cint func1(int,int); int func2(int x,int y) { int resfunc1(x,y); return res3; }main.c#include stdio.h #include stdlib.h int func2(int,int); int main() { int a15,b2; printf(func2(a,b)%d\n,func2(a,b)); system(pause); }实现思路:首先将mod1编译为m1.dll然后将mod2编译为m2.obj并将m2.obj打包为m2.lib最后编译main.c并引用m2.lib和m1.dll生成main.exe将m1.dll拷贝至main.exe同目录,双击运行即可看到效果实验十一、gcc动态库引用静态库mod1是静态库,mod2是动态库并且引用mod1,主模块引用mod2目录结构:mod1m1.hm1.cmod2m2.hm2.cmain.c代码:m1.h#ifndef MOD1 #define MOD1 int func1(int,int); #endifm1.cint func1(int x,int y) { return xy; }m2.h#ifndef MOD2 #define MOD2 int func2(int,int); #endifm2.cint func1(int,int); int func2(int x,int y) { int resfunc1(x,y); return res6; }main.c#include stdio.h #include stdlib.h int func2(int,int); int main() { int a12,b3; printf(func2(a,b)%d\n,func2(a,b)); system(pause); }实现思路:首先将m1.c编译为m1.obj并打包为m1.lib然后将m2.c编译为m2.dll(gcc -shared m2.c ../mod1/m1.lib -o m2.dll)最后编译主模块,引用了m2.dll,将m2.dll拷贝至main.exe同目录,双击main.exe即可看到效果1.将m1.c编译为m1.obj并打包为m1.libcd mod1gcc -c m1.c -o m1.objar -crv m1.lib m1.obj2.将m2.c编译为m2.dllcd ../mod2gcc -shared m2.c ../mod1/m1.lib -o m2.dll3.编译main.ccd ..gcc main.c mod2/m2.dll -o main.exe然后将m2.dll拷贝至main.exe同目录,双击main.exe即可看到效果
返回列表