Ошибка определения множественного обработчика ошибок GSL при связывании

В настоящее время я пытаюсь использовать ранее написанную мной библиотеку (matrix.c) в другой самозаписываемой библиотеке (Quaternion.c), вызывая ее через заголовочный файл, используя стандартный метод использования файла matrix.h с прототипы функций из файла "matrix.c".

"matrix.c" работает, но когда я пытаюсь скомпилировать "Quaternion.c" в MSYS2 MinGW64, используя:

gcc -c matrix.c 

gcc -c Quaternion.c 

gcc matrix.o Quaternion.o -o Quaternion -lgsl

Я получаю эту ошибку:

C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: Quaternion.o:Quaternion.c:(.text+0x0): multiple definition of `my_handler'; matrix.o:matrix.c:(.text+0x0): first defined here

collect2.exe: ошибка: ld вернул 1 состояние выхода

Я определил собственный обработчик ошибок в GSL "errono.h", и я предполагаю, что это источник ошибки:

void my_handler (const char * reason, const char * file,  int line, int gsl_errno){

  if(gsl_errno == 3 || gsl_errno == 7 || gsl_errno == 8 || gsl_errno == 10){
    printf("Fatal memory-based error %d, resetting\n", gsl_errno);
    exit(0);
    //Reset Chip
  }
  if(gsl_errno == 1 || gsl_errno == 2 || gsl_errno == 4){
    printf("User error %d (%s), ignoring calculation and moving forward\n", gsl_errno, reason);
    // Return/ignore calculation
  }
  else
    printf("Unexpected error %d, ignoring and moving forward\n", gsl_errno);
    // Return/ignore calculation
}

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

1 ответ

Решение

Переместите цитату в один из файлов.c.
Затем предоставьте только прототип в файле.h.

void my_handler (const char * reason, const char * file,  int line, int gsl_errno);

В противном случае функция определяется один раз для каждого файла.c, который компилируется и выполняет #include этого заголовка. В твоем случае наверное дважды.

Защита от повторного включения не поможет в этом случае, потому что это все еще происходит один раз для скомпилированного файла.c. Но иметь охранника - все еще хорошая идея, я полагаю, у вас есть.

Другие вопросы по тегам