繁体   English   中英

如何编译具有多个主函数的C项目?

[英]How to compile a C project with more than one main function?

我是C的新手,现在阅读一些教科书并开始应用它的例子。

问题是,每当我创建一个新项目并尝试放置包含main函数的多个文件时,链接器(正如我thougt0解释说的那样:

/home/mohammed/tmp/abcd/main.c:4: multiple definition of `main'

(顺便说一句,我使用了很多IDE,MonoDevelop,QT创建者,VS2010,Codebloks,...)我目前使用QT Creator,它似乎是一个非常好的IDE。

那么,解决这样的问题没有办法解决?

编辑:

我问,因为我正处于学习阶段,现在不做真正的编程。 我只需要一种简单的方法来在C中创建程序,而不必为每个书籍示例创建一个单独的项目。 同时,我不想使用Gedit / VI +命令行。

那么,有没有任何方法,如清理项目,然后编译 - 只需一个文件,我需要运行??? 顺便说一句,在JAVA中我们可以运行一个程序,它包含多个主程序(IDE给我选择)

你想用多个main功能做什么?

如果你正在尝试编译一次多个不同的程序,你需要单独编译每一个(即只有一个main每程序)。

如果你正在尝试编译一个程序,并希望多个main功能的全部运行,你不能。 您只需要指定一个main并将其他main重命名为其他内容(并按照您希望它们运行的​​顺序从单个main中调用它们)。

如果您只是尝试使用其中一个main功能作为程序的单个入口点而忽略其他功能,则在链接时不应将文件与其他main包括在一起。 如果您希望保留它们,我建议将每个main放在一个单独的文件中,并且在链接/编译时只包含其中一个主文件。

如果您错误地收到此错误,那么您可能在IDE中执行了错误的项目。 也许你不小心尝试将多个不同的程序编译成一个? 您可能需要将包含main每个文件指定为单独的构建产品。 C不像Java那样你可以在每个类中放入一个main方法并指定要调用的方法; C中的main是全局名称。

您的应用程序中不可能有多个入口点。 启动最终可执行文件时,将调用入口点函数(main) 这一点不能模棱两可。

所以,如果你想逐个调用它们,你可以像这样链接它们:

void main1() {} /* Note that these aren't called main. */
void main2() {}
...

int main(int argc, char* argv[]) {
    main1();
    main2();
    return 0;
}

您甚至可以使用线程(例如boost.Thread)调用它们,以便它们并行运行。 但是你不能将多个名为main函数链接在一起。

如果您希望它们分别是单独的程序,则必须单独链接它们。

每个程序必须只有一个主要功能。 但是,main可以调用你想要的任何函数(包括它自己,虽然这可能会令人困惑)。 因此,您应该将程序分解为逻辑部分。

正如许多人所说,每个程序只能有一个主程序。 在阅读本书时,您不希望为每个示例创建一个新项目的麻烦。 这是可以理解的,但基本上你必须这样做。 我看到两种选择:

  1. 在IDE中使用新项目功能(如VS2010)。 这将为您完成所有艰苦的工作。 您可以随时删除它们。
  2. 如果您不关心代码,只需清空文件(甚至是main()函数)并重新使用它。 使用书籍示例,您可能永远不会重新访问代码,因此只需删除它就可以了。

如果每个main将在构建目录树中对应不同的可执行文件,则在同一项目中可以有多个main。

以下示例使用CMake,我不知道是否可以使用其他构建过程管理器软件。

将以下两个.cpp文件存储在名为source的文件夹中,并将它们命名为square_root.cpp和power_of_two.cpp:

square_root.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main (int argc, char *argv[])
{

  if (argc < 2) {
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
  }

  double inputValue = atof(argv[1]);
  double outputValue = sqrt(inputValue);
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);

  return 0;
}

power_of_two.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main (int argc, char *argv[])

{
  if (argc < 2) {
      fprintf(stdout,"Usage: %s number\n",argv[0]);
      return 1;
  }

  double inputValue = atof(argv[1]);
  double outputValue = inputValue*inputValue;

  fprintf(stdout,"The power of two of %g is %g\n",
          inputValue, outputValue);

  return 0;
}

请注意,它们都包含方法main。 然后,在同一个文件夹中,添加一个名为CmakeLists.txt的.txt:它将告诉编译器可执行文件的数量,如何调用它们以及在哪里找到main(s)。

的CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)
project (Square_and_Power)
add_executable(Square2 square_root.cpp)
add_executable(Power2 power_of_two.cpp)

在源的同一根中创建一个名为build的新文件夹,然后使用cmake进行配置和生成。 看一下在文件夹构建中创建的文件夹的结构。 在构建中打开终端并输入make

 →  make
[ 50%] Built target Power2
Scanning dependencies of target Square2
[ 75%] Building CXX object CMakeFiles/Square2.dir/square_root.cpp.o
[100%] Linking CXX executable Square2
[100%] Built target Square2

如果没有错误发生,您将有两个可执行文件:Square2和Power2。

→  ./Square2 5
The square root of 5 is 2.23607
 →  ./Power2 5
The power of two of 5 is 25

所以你有两个主要编译两个不同应用程序的项目。 然后,两个cpp文件可以在项目中的其他.cpp或.h文件中共享相同的标头和其他方法。 我建议你看看cmake教程https://cmake.org/cmake-tutorial/ 。如果不是相同的结果可能还有其他类似的方法,但我不知道。 希望其他用户将为此主题做出贡献!

实际上,我发现Dev-C ++支持处理不属于任何项目的多个主文件,因此我可以根据需要创建一个运行尽可能多的文件。

谢谢所有在这里合作的人:)祝所有人好运。

此外,对于Linux / win,我发现Code :: Blocks可以做到这一点。 谢谢。

我认为QtCreator是一个很棒的IDE。

为了学习和测试,能够使用多个主电源以便于使用会很好,但是如前所述,您只能有一个主电源,因为这是在QTcreator / .pro qmake文件中定义项目的方式。

您可以在pro或make / CMAKE文件中创建多个目标。

但是对于测试,我在项目的.pro文件中做了这个。


MAIN = simpletree_test.c

SOURCES += \
    $$MAIN \
    simpletree.c \
    graph_tree.c \
    redblacktreenode.c \
    redblacktree.c \
    redblack.c \
    pointers.c

HEADERS += \
    simpletree.h \
    graph_tree.h \
    redblacktreenode.h \
    redblacktree.h \
    redblack.h \
    pointer_manipulator.h

message("The project contains the following files:")
message($$SOURCES)

所以我只是在pro文件中交换名为MAIN的变量中的主文件名。 在SOURCES变量中使用它。

正如您所看到的,我测试了几种树的实现。 现在正在测试树的简单变体,我在测试特定节点的新实现之前,在平衡树上测试它们。

然而,这个方法并不完美,因为你不能为函数等提供相同的名称。过了一段时间我很难为find_node()或traverse_tree()创建新的名字。

在QtCreator中,您可以右键单击文件并选择“编译”选项,该选项仅编译所选文件和所需的依赖项。 因此,如果你编译一个这样的主文件,并且该文件不包含任何其他主文件,这应该可行。

我猜你的一个IDE会自动创建一个带有main函数的文件。 检查周围是否已经创建了一个。

你不能有多个main定义。 “主要”功能实质上是定义程序的功能。 如果您有多个main副本,您希望执行哪个副本?

你的问题的解决方案是使用库; 如果你想重用功能,那么你应该创建一个库,它与程序基本相同,只是它有功能和数据(如程序),它没有一个叫做“main”的特殊功能,因此没有“入口点”,执行应该在操作系统双击或以其他方式加载时开始。 库有两种变体:共享/动态和静态。 任何人都应该这样做。 您创建的每个程序都有自己的主要功能,但您可以在不同程序中重复使用您的库而不会出现任何问题。

现在关于创建库的实际元素...请参阅我的C ++库项目模板

正如其他人所说,您的项目可能只有一个主要功能。

你为什么要尝试多个主要功能? 是因为您将多个小示例程序放入一个项目中,并且每个项目都有一个主要的? 如果是这种情况,您可能需要为每个示例创建一个单独的项目,以便IDE不会要求编译器将来自多个示例的源代码编译/链接到一个程序中。 您的IDE也可能支持像目标这样的概念,它允许您在一个项目中保留多个相关程序的代码,而不是选择实际构建的程序(目标)。 然后,IDE将仅编译/链接该目标中的文件。

尝试使用static关键字,例如:

file1.cpp:

#ifdef RUN_FILE1
#define STATIC static
#else
#define STATIC
#endif

int STATIC main(int argc, char **argv(){}

file2.cpp:

#ifdef RUN_FILE2
#define STATIC static
#else
#define STATIC
#endif

int STATIC main(int argc, char **argv(){}

用于编译add /DRUN_FILE2/DRUN_FILE1

只是一个想法。

如果您正在使用MS链接器,请使用/ FORCE:MULTIPLE链接器选项。 遇到的第一个主要符号将获胜。 不确定其他连接器的选项是什么。

我能找到的最佳解决方案是Eclipse每次创建项目以运行单个文件? 它有一些替代方案,而不是为每个程序创建一个新项目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM