2012-05-04 3 views
4

Я хочу включить файл .c в другой. Возможно ли это правильно? Это хорошо работает, если я включаю заголовочный файл в .c файле, но не работает, если я включаю файл .c в другой .c файл.
Я использую Visual Studio, и я получаю следующее сообщение об ошибке:Включить файл c в другой

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. :)

+2

Как вы связываетесь? –

+2

Включение файла '* .c' внутри другого' * .c' очень плохого вкуса (для новичков). Оставьте это экспертам. –

+2

@BasileStarynkevitch: это плохая практика для экспертов. Верьте или нет, компиляция и связывание кучки меньших единиц перевода менее сумасшедшая, чем попытка скомпилировать одну огромную единицу перевода. –

ответ

0

Вы, вероятно, определили два раза эта функция

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

один в текущем файле и один в sayhello.c

Вы должны удалить одно определение.

+0

@Bernoit это не тот случай – Andrew

+3

@ Андрю: Доверьтесь линкеру, он знает. –

8

Это работает, но вам нужно быть осторожным с тем, как вы создаете программу. Кроме того, как отмечают в комментариях люди, это обычно считается плохой идеей. Это неожиданно, и это создает такие проблемы. Есть немного преимуществ, особенно для того, что кажется тривиальной программой. Вероятно, вам следует пересмотреть этот подход в целом.

После того, как вы сделали что-то подобное, вы должны только компилировать main.c, а не пытаться связать его с результатом компиляции sayHello.c, который вы, кажется, делаете.

Возможно, вам потребуется указать Visual Studio на exclude the latter file from the build.

+0

как я могу исключить его из сборки? – Andrew

+1

@ Андрей, я связался с вопросом об этом. :) – unwind

1

Это ошибка компоновщика. После компиляции всех ваших .c-файлов в .obj-файлы (сделанные компилятором) компоновщик «объединяет» их вместе, чтобы сделать вашу dll/exe. Линкер обнаружил, что два объекта объявляют одну и ту же функцию (что явно не допускается). В этом случае вы хотели бы, чтобы компоновщик обрабатывал только main.obj, а не sayhello.obj (так как его код уже включен в main.obj).

Это потому, что в main.obj вы также будете иметь функцию sayHello() из-за включения!

0

sayHello.h

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

main.c

#include "sayHello.h" 

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

I want to include a .c file in another.

Нет вы не делаете. Вы действительно, действительно нет. Не принимайте любых шагов по этому пути; это только заканчивается болью и страданиями. Это плохая практика даже для тривиальных программ, таких как ваш пример, а тем более для программ любой реальной сложности. Тривиальное однострочное изменение в одном файле потребует от вас восстановления как этого файла, так и всего, что включает его, что является пустой тратой времени. Вы теряете возможность контролировать доступ к данным и функциям; все во включенном файле .c отображается в файл включительно, даже функции и переменные области видимого файла объявлены static. Если вы завершите работу, включая файл .c, который включает в себя другой файл .c, который содержит другой файл .c и так weiter, вы можете завершить работу с слишком большой единицей перевода для компилятора.

Отдельная компиляция и увязка - это недвусмысленная Хорошая вещь. Единственные файлы, которые вы должны включить в свой.c - файлы заголовков, которые описывают интерфейс (определения типов, объявления прототипов функций, макроопределения, внешние объявления), а не реализация.

Смежные вопросы