Файл .c через заголовок моста не работает после обновления Xcode 8

Приложение, над которым я работал, использует внешнюю библиотеку pdlib, у которой есть собственные внешние файлы (файлы .c), которые я импортировал через связующий заголовок #import "Uzi.c" и вызывал мой основной файл Swift через функцию настройки Uzi.c Uzi_setup() в моем ViewController классе. У меня не было проблем с этим до тех пор, пока несколько дней назад я не обновился до нового общедоступного Xcode 8 (летом у меня не было проблем с Xcode 8 Beta 1).

Вот 7 ошибок, которые я получаю, перечисленные под одним зонтиком «Mach-O Linker Error»:

Undefined symbols for architecture x86_64:
"_Uzi_bang", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_class", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_float", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_new", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_pause", referenced from:
  _Uzi_setup in ViewController.o
"_Uzi_resume", referenced from:
  _Uzi_setup in ViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Эти неопределенные символы представляют собой 6 функций и объявление класса из Uzi.c. Вот ссылка на весь файл c: https://github.com/electrickery/pd-miXedSon/blob/master/hammer/Uzi.c

Я пробовал каждое решение, которое я нашел в Интернете для решения подобных проблем, но решения пока нет... Я попытался изменить настройки «Архитектура» и «Действительная архитектура» только на armv7 и armv7s (без arm64) и изменил «Сборка Только активная архитектура» на «Нет». Этот шаг, кажется, помогает другим в подобных ситуациях, но они не сработали для меня (и удаление arm64 приводит к появлению дополнительных ошибок).

XCode 8 появился совсем недавно (общедоступная версия была выпущена 13 сентября), так что практически нет других вопросов об этом обновлении, вызывающем аналогичную проблему.

Любая помощь будет принята с благодарностью!


person PlateReverb    schedule 27.09.2016    source источник
comment
Возможный дубликат Неопределенная ссылка C++   -  person too honest for this site    schedule 28.09.2016
comment
@Olaf Я не вижу, чтобы мой файл .C был связан более одного раза. Эта другая ссылка, похоже, не относится к моей проблеме, но если да, не могли бы вы сказать мне, как это может быть?   -  person PlateReverb    schedule 28.09.2016
comment
Это файл .C или .c? Первым будет C++, а не C.   -  person too honest for this site    schedule 28.09.2016
comment
@Olaf Это файл .c (я исправил в заголовке вопроса). Большая часть моего приложения написана на Swift. Я просто подключаюсь к этому внешнему через заголовок моста. У меня не было проблем с этим до последней версии Xcode 8.   -  person PlateReverb    schedule 28.09.2016
comment
Является ли файл C целевым членом вашего исполняемого файла?   -  person zneak    schedule 28.09.2016
comment
@zneak Да, это так.   -  person PlateReverb    schedule 28.09.2016
comment
Кстати, ошибка связана с x86_64 (он же amd64), я не думаю, что изменение чего-либо с помощью arm64 решит эту проблему.   -  person umläute    schedule 20.10.2016


Ответы (1)


Решено @danomatika на GitHub: https://github.com/libpd/libpd/issues/149< /а>

«Как правило, вам не следует включать/импортировать файл реализации, также известный как .c, .cpp, .m и т. д. Это то, что вызывает проблему дублирования символов.

Это то, для чего предназначено «объявление прямой функции» в заголовочном файле: чтобы сообщить компилятору, что функция существует и какие данные она принимает/возвращает. Затем компилятор предполагает, что фактическая реализация функции существует в файле реализации. Если его не удается найти, вы получаете «ошибку неопределенного символа». Если вы каким-то образом в конечном итоге объявите функцию дважды, то есть включите заголовок с предварительным объявлением и реализацию самой функции в файле .c, вы получите «ошибку повторяющегося символа».

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

Для этого есть два простых решения, каждое из которых включает объявление требуемой функции, которую вы хотите вызвать из файла .c в заголовочном файле.

  1. Просто объявите функцию в заголовке моста:

    void uzi_setup();

  2. Создайте заголовок, скажем, Externals.h, и объявите там все внешние элементы:

    // forward declare setup functions only found in .c implementations void uzi_setup();

    // convenience wrapper function void externals_setup() { uzi_setup(); }

    Затем импортируйте файл в заголовок моста:

    #import "Externals.h"

    И быстро теперь вы можете сделать:

    externals_setup()

person PlateReverb    schedule 28.09.2016