В стороне статья, связанная с @vcldeveloper, имеет хорошее объяснение некоторых распространенных проблем. Трюк предоставления отсутствующих функций C RTL в коде Pascal превосходный и намного быстрее, чем попытка связать необходимые функции в виде файлов C или даже как .obj-файлы.
Однако у меня есть подозрение, что я знаю, что здесь происходит. Я использую этот же подход, но на самом деле имеет более 100 файлов .obj в устройстве. Я обнаружил, что когда я добавляю новые, я получаю ту же ошибку компоновщика, что и вы. Способ, которым я обхожу это, - попробовать переупорядочить мои инструкции LINK. Я пытаюсь добавить новые файлы obj один за другим, и я всегда мог, в конце концов, обойти эту проблему.
Если ваши файлы C полностью автономны, вы можете поместить их в другую единицу, и компоновщик справится с этим. Однако я сомневаюсь, что это так, и действительно, я подозреваю, что если они действительно были автономными, то эта проблема не возникла бы. Кроме того, желательно иметь инструкции $ LINK в одном устройстве, так что любые функции RTL, которые должны быть поставлены, могут поставляться один раз и один раз (они должны отображаться в том же блоке, что и команды $ LINK).
Эта странность в линкере присутствовал в Delphi 6 и присутствует в Delphi 2010.
EDIT 1: Реализация теперь до меня дошло, что этот вопрос, вероятно, из-за Delphi с использованием одного прохода компилятора , Я подозреваю, что ошибка «отсутствует внешняя ссылка» связана с тем, что компилятор обрабатывает файлы .obj в том порядке, в котором они появляются в устройстве.
Предположим, что a.obj появляется перед b.obj, и все же a.obj вызывает функцию в b() b.obj. Компилятор не будет знать, где находится b(), в точке, где требуется исправление вызова функции. Когда я нахожу время, я попытаюсь проверить, действительно ли эта гипотеза правдоподобна!
И, наконец, еще один простой выход из проблемы заключается в объединении a.c, b.c и c.c в один файл C, который, по моему мнению, обходит эту проблему для OP.
Edit 2: Я нашел другое переполнение стека вопрос, который покрывает эту землю: stackoverflow.com/questions/3228127/why-does-the-order-of-linked-object-file-with-l-directive-matter
Редактировать 3: Я нашел еще один действительно прекрасный способ обойти эту проблему.Каждый раз, когда компилятор жалуется
[DCC Error] Unit1.pas(1): E2065 Unsatisfied forward or external declaration: '_a'
вы просто добавляете в секции реализации блока, заявление так:
procedure _a; external;
Если это рутина, что вы хотите позвонить из Delphi, то вам явно необходимо получить список параметров, вызывая соглашения и т. д. правильно. В противном случае, если это обычная внутренняя процедура для внешнего кода, вы можете игнорировать список параметров, вызывать соглашения и т. Д.
Насколько я знаю, это единственный способ импортировать два объекта, которые ссылаются друг на друга в круговым способом. Я считаю, что объявление внешней процедуры таким образом сродни тому, чтобы сделать декларацию. Разница заключается в том, что реализация обеспечивается объектом, а не кодом Паскаля.
Теперь я смог добавить еще несколько инструментов в свой арсенал - спасибо, что задали вопрос!
Мое предположение: «b_function()» или «c_function()» не найдено ни в одном из трех объектных файлов. Вы предполагаете, что проблема связана с связыванием нескольких объектных файлов, и вы доказали, что можете связать один файл. Вы пытались связать, например, только «b.obj» и импортировать только «b_function()»? –
Возможно, эта статья Руди Велтиуса могла бы помочь: http://rvelthuis.de/articles/articles-cobjs.html – vcldeveloper