首页 > 解决方案 > c中的多重编译和main()函数

问题描述

我有一个与 gcc 用于编译不同文件的功能有关的问题。

我的目标是有一个程序(参见 script1.c),它会在每次运行时加载(编译?)来自 script2.c 和 script3.c 文件的函数。

这就是我的脚本应该的样子(不得更改 script2.c 和 script3.c 文件中函数的名称(2main()和 1 ))。init()

脚本1.c:

int main(int argc, char *argv[]){
  printf("loaded main() in script1.c\n");
  int ret = main(argc, argv); // main() script2.c
  if(ret == 0){
    init(argc, argv); // init() script3.c
    ret = main(argc, argv); // main() script3.c
    if(ret == 0){
      ret = main(argc, argv); // main() script3.c
    }
  }
  return(ret);
}

脚本2.c:

int main(int argc, char *argv[]){
  printf("loaded main() in script2.c\n");
  return(0);
}

脚本3.c:

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 init() in script3.c\n");
  }
  return(0);
}

我想退货:

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()从逻辑上讲,我在函数上有循环。

以下是我可以尝试的不同方法:

  1. main()将script1.c的函数名改为 ,编译时_start()使用“ ”选项。-Wl,--allow-multiple-definition -nostartfiles结果:main()script2.c 函数的错误被逻辑初始化了 2 次。
  2. 使用script1.c 中的system()和函数编译/运行 scripts2.c 和 script3.c。结果:在函数之前exec执行函数的 script3.c 出错。我认为,我需要一个与 " " 选项等效的工作才能使其正常工作。main()init()-Wl, -init, init
  3. 在函数中添加属性((constructor)) init(),使其在main()script3.c之前启动。问题是,在我的示例中,该init()功能将启动 2 次:

标签: gcc

解决方案


这是一个可能类似于您正在尝试做的事情的示例。我有一个主函数和三个辅助函数,分别命名为 func1、func2 和 func3。它们都驻留在同一个目录中。每个函数都在自己的源文件中,为清楚起见以函数命名(但源文件名是任意的)。main(),程序的“入口点”,调用func1,然后调用func2;func2 依次调用 func3。每次都忠实地传递 main() 的参数并输出。

在一个典型的程序中,还会有一个头文件,其中包含所有三个辅助函数的函数声明;但在这个小例子中,人们可以简单地手动编写它们。

功能1.c:

#include <stdio.h>

void func1(int argc, char **argv)
{
    printf("func1: Called with the following arguments:\n");
    for(int i = 0; i<argc; i++)
    {
        printf("func1, arg. %d (index %d): ->%s<-\n", i+1, i, argv[i]);
    }
    printf("func1: Returning\n");
}

功能2.c:

#include <stdio.h>

extern void func3(int, char **);

void func2(int argc, char **argv)
{
    printf("func2: Calling func3\n");
    func3(argc, argv);
    printf("func2: returning\n");
    
}

函数3.c

#include <stdio.h>

void func3(int argc, char **argv)
{
    printf("func3: Called with the following arguments:\n");
    for(int i = 0; i<argc; i++)
    {
        printf("func3, Arg. %d (index %d): ->%s<-\n", i+1, i, argv[i]);
    }

    printf("func3: Returning\n");
}

和 main.c:

#include <stdio.h>

extern void func1(int, char **);
extern void func2(int, char **);

int main(int argc, char **argv)
{
    printf("main(): Called with the following arguments:\n");
    for(int i = 0; i<argc; i++)
    {
        printf("Arg. %d (index %d): ->%s<-\n", i+1, i, argv[i]);
    }

    printf("********* main(): Calling func1 *********\n");
    func1(argc, argv);

    printf("********* main(): Calling func2 *********\n");
    func2(argc, argv);
}

示例会话:编译

$ gcc -Wall -o main main.c func1.c func2.c func3.c

然后用例如执行

$ ./main 1 2 3

输出:

Arg. 1 (index 0): ->./main<-
Arg. 2 (index 1): ->1<-
Arg. 3 (index 2): ->2<-
Arg. 4 (index 3): ->3<-
********* main(): Calling func1 *********
func1: Called with the following arguments:
func1, arg. 1 (index 0): ->./main<-
func1, arg. 2 (index 1): ->1<-
func1, arg. 3 (index 2): ->2<-
func1, arg. 4 (index 3): ->3<-
func1: Returning
********* main(): Calling func2 *********
func2: Calling func3
func3: Called with the following arguments:
func3, Arg. 1 (index 0): ->./main<-
func3, Arg. 2 (index 1): ->1<-
func3, Arg. 3 (index 2): ->2<-
func3, Arg. 4 (index 3): ->3<-
func3: Returning
func2: returning

您可以看到程序的第一个参数是由命令 shell 和 C 运行时库放入它们的:它是调用程序的字符串,这是习惯性的,这里是“./main”。只有在那之后才会出现显式命令行参数“1”、“2”和“3”。


推荐阅读