C语言多文件编译多main()与init()函数按需加载实现问题
解决多C文件同名main函数调用冲突方案
核心解决思路是将script2.c、script3.c分别编译为独立的动态共享库,在script1.c中通过动态加载接口按需获取对应函数地址调用,完全规避符号冲突问题,且无需修改原有函数名称。
步骤1:修正代码语法并补充动态加载逻辑
script1.c 代码(新增动态加载逻辑)
#include <stdio.h> #include <dlfcn.h> int main(int argc, char *argv[]) { printf("loaded main() in script1.c\n"); void *handle2 = dlopen("./libscript2.so", RTLD_LAZY); void *handle3 = dlopen("./libscript3.so", RTLD_LAZY); // 定义对应函数指针类型 typedef int (*main_func)(int, char**); typedef void (*init_func)(int, char**); // 调用script2的main main_func main2 = dlsym(handle2, "main"); int ret = main2(argc, argv); if (ret == 0) { // 调用script3的init init_func init3 = dlsym(handle3, "init"); init3(argc, argv); // 两次调用script3的main main_func main3 = dlsym(handle3, "main"); ret = main3(argc, argv); if (ret == 0) { ret = main3(argc, argv); } } // 关闭动态库句柄 dlclose(handle2); dlclose(handle3); return ret; }
script2.c 补充必要头文件
#include <stdio.h> int main(int argc, char *argv[]) { printf("loaded main() in script2.c\n"); return 0; }
script3.c 补充必要头文件(省略逻辑保留原有函数名)
#include <stdio.h> #include <string.h> #include <stdlib.h> void init(int argc, char *argv[]) { argv[0] = (char*)strdup("OK"); printf("loaded init() in script3.c\n"); } int main(int argc, char *argv[]) { if(strcmp(argv[0], "OK") == 0) { printf("loaded main() in script3.c\n"); } return 0; }
步骤2:执行编译命令
- 编译script2为动态库:
gcc -fPIC -shared -o libscript2.so script2.c - 编译script3为动态库:
gcc -fPIC -shared -o libscript3.so script3.c - 编译主程序script1,链接动态加载库dl:
gcc -o script1 script1.c -ldl
步骤3:运行验证
执行./script1即可得到期望输出:
loaded main() in script1.c loaded main() in script2.c loaded init() in script3.c loaded main() in script3.c loaded main() in script3.c
原方案失效原因说明
- 静态链接允许多重定义的方案:同一全局符号只会保留最先加载的实例,无法区分不同文件的同名main函数,还会出现递归调用死循环。
- exec/system调用方案:启动独立进程默认从目标程序的main函数开始执行,无法控制先调用init函数再执行main。
- constructor属性方案:构造函数会在动态库加载时自动执行,无法做到按需调用,会出现额外的触发次数。
内容的提问来源于stack exchange,提问作者Kryk
相关产品推荐
相关产品推荐

