Я работаю над заголовочным файлом, который выполняет для меня пару функций. Я включаю файл заголовка в два отдельных файла, файл c и основной файл.
Я использую #ifndef
и #def
, но похоже, что он все еще компилируется дважды, потому что в процессе компоновки я получаю serveral
multiple declarations of ...
ошибки.
#ifndef PLL_HEADER
#define PLL_HEADER
/********************************************************************
* includes
********************************************************************/
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "PITDriver.h"
// Some more stuff
#endif
[compiling stuff]
Building target: PLL Function.axf
Invoking: MCU Linker
[other linker stuff]
./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:45: multiple definition of `accumulateVal'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:45: first defined here
./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:46: multiple definition of `getValOne'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:46: first defined here
./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:47: multiple definition of `getValTwo'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:47: first defined here
./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:48: multiple definition of `countTo'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:48: first defined here
./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:49: multiple definition of `runUntil'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:49: first defined here
./source/main.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:50: multiple definition of `currentValue'
./source/PLL.o:C:\Users\mailn\Desktop\Work\Sparton\MCUXPresso Workstation\PLL Function\Debug/../source/PLL.h:50: first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:39: PLL Function.axf] Error 1
У вас есть реализовано функция в самом заголовочном файле?
Исправление сделано по комментарию @Peter
В C вы можете помещать определения переменных в заголовок только в том случае, если он включен только в одну единицу компиляции.
Кажется, у вас есть два модуля компиляции:
тот, который компилирует ваши PLL.h и PLL.c для создания PLL.o
тот, который компилирует ваш main.c и PLL.h для создания main.o
Оба ваших объектных файла содержат переменные, которые вы определили в PLL.h, и поэтому, когда вы нажимаете на компоновщик, он выдает ошибку, потому что переменные были объявлены дважды (по одному разу в каждом объектном файле).
Чтобы исправить эту ошибку, вы можете либо изменить способ компиляции, либо объединить два модуля компиляции. Или (если вы используете IDE, которая автоматически обрабатывает вашу компиляцию) вы можете применить следующие изменения, чтобы избежать определения переменной в вашем заголовке.
В заголовке: (изменить определение на объявление)
extern int x;
В исходном файле: (определить переменную)
int x;
Наличие определения переменной в заголовке не является запрещенный. Однако заголовок, определяющий переменную, может быть включен ТОЛЬКО в одну единицу компиляции. Если она включена в две или более единицы компиляции, эта переменная будет определена в программе несколько раз. (Согласно стандарту, который дает неопределенное поведение, но на практике это обычно приводит к ошибкам «множественного определения» при связывании).
Спасибо за исправление, я не знал об этом, вы хотите исправить мой ответ или хотите, чтобы я это сделал?
Похоже, у вас, вероятно, есть реальные переменные с хранилищем, расположенным в вашем заголовочном файле. Включить охранников не защитить от этого. Поместите эти переменные в PLL.c и пометьте
extern
-отмеченными версиями этих переменных в заголовке. Таким образом, оба файла могут ссылаться на переменную, но она существует только в одном месте.