将c文件包含在另一个文件中

时间:2012-05-04 11:35:02

标签: c

我想在另一个文件中包含.c文件。有可能吗?如果我在.c文件中包含头文件,它可以正常工作,但如果我在另一个.c文件中包含.c文件,它也不能正常工作。
我正在使用Visual Studio,我收到以下错误:

main.obj : error LNK2005: _sayHello already defined in sayHello.obj  
/* main.c  */
#include "sayHello.c"

int main()
{
    return 0;
}  
/* sayHello.c */

#include <stdio.h>

void sayHello()
{
    printf("Hello World");
}

我不知道这个错误可能意味着什么。是时候问更高级的C编码员了。 :)

8 个答案:

答案 0 :(得分:19)

  

我想在另一个文件中包含.c文件。

不,不。你真的,真的没有。不要在此路径中执行任何步骤;它只会以痛苦和痛苦结束。这对于像你的例子这样的琐碎程序来说是不好的做法,对于任何真正复杂的程序来说都是如此。一个文件中的一个简单的单行更改将要求您重建该文件和包含它的任何内容,这是浪费时间。您失去了控制数据和功能访问的能力;包含的.c文件中的所有对包含文件是可见的,甚至是声明为static的函数和文件范围变量。如果您最终包含一个.c文件,其中包含另一个.c文件,其中包含另一个.c文件 und so weiter ,您最终可能会遇到一个太大的转换单元,无法让编译器处理。

单独的编译和链接是一个明确的好事。您应该包含在.c文件中的唯一文件是描述接口(类型定义,函数原型声明,宏定义,外部声明)的头文件,而不是实现。

答案 1 :(得分:9)

它有效,但您需要小心如何构建程序。此外,正如人们在评论中指出的那样,这通常被认为是一个坏主意。这是意料之外的,它会产生这样的问题。很少有benetfits,特别是对于看似简单的程序。你应该重新考虑这种方法。

执行此类操作后,您应该只编译main.c,而不是尝试将其与编译sayHello.c的结果相关联,而您似乎正在这样做。

您可能需要告诉Visual Studio exclude the latter file from the build

答案 2 :(得分:1)

这是链接器错误。在将所有.c文件编译为.obj文件(由编译器完成)之后,链接器将它们“合并”在一起以生成dll / exe。链接器发现两个对象声明了相同的功能(显然不允许)。在这种情况下,您希望链接器只处理main.obj而不是sayhello.obj(因为它的代码已包含在main.obj中)。

这是因为在main.obj中你也会因为include而拥有sayHello()函数!

答案 3 :(得分:0)

您可能已将此功能定义为两次

void sayHello()
{
printf("Hello World");
}

当前文件中的一个和sayhello.c中的一个

您必须删除一个定义。

答案 4 :(得分:0)

sayHello.h

#include <stdio.h>
void sayHello(void);

<强>的main.c

#include "sayHello.h"

int main()
{
    sayHello();
    return 0;
}  

答案 5 :(得分:0)

是的,任何&#39; .c&#39;文件可以包含在另一个程序中。 其中包括&#39; .h&#39;文件像&#39; stdio.h&#39;在该计划中。 之后我们可以将这些函数调用到这个外部文件中。

test.c的::

#include<stdio.h>
#include<conio.h>
void xprint()
{
    printf("Hello World!");
}

的main.c ::

#include "test.c"
void main()
{
   xprint();
   getch();
}

输出:: Hello World!

答案 6 :(得分:0)

问题似乎是 sayHello.c 被编译成一个名为 sayHello.obj 的目标文件,而 main.c(还包括来自 sayHello.c 的所有源文本)被编译进入 main.obj,因此两个 .obj 文件都从 static 获得了所有外部符号(如非 sayHello.c 函数定义)的副本。

然后应该将所有目标文件“链接”在一起以生成最终的可执行程序文件,但是当任何外部符号出现不止一次时,链接就会中断。

如果您发现自己处于这种情况,您需要停止将 sayHello.obj 链接到 main.obj(然后您可能根本不想将 sayHello.c 自身编译成它自己的目标文件).

如果您手动控制构建的每个步骤(就像您在使用编译器的 CLI 时所做的那样),这通常只是从链接器或编译器的调用中排除该目标文件的问题。

由于您使用的是 Visual Studio,它可能会为您做出一系列假设,例如“每个 .c 文件都应该编译成自己的目标文件,并且所有这些目标文件都应该链接在一起”,并且您必须找到一种方法来规避或禁用 sayHello.c 的这种假设。

一种简单且有点惯用的解决方案可能是将 sayHello.c 重命名为 sayHello.c.inc

答案 7 :(得分:0)

//THIS IS THE MAIN FILE//
#include "test.c"
int main()
{
    multi(10);
}


//THIS IS THE TEST FILE//
#include<stdio.h>
void multi(int a)
{
    printf("%d",a*2);
}

注意事项:

  1. 这里需要运行包含“main()”函数的程序。
  2. 您可以避免在主函数中使用“stdio.h”头文件。因为,您要包含已经包含“stdio.h”头文件的文件。
  3. 您必须从“主”文件中调用该函数。
  4. 包含的文件应该是“file_name.c”而不是“file_name.h”。因为通常我们对头文件使用 .h 扩展名。因为我们要包含另一个程序文件而不是头文件,所以我们必须使用 .c。否则它会给你致命错误并且编译被终止。