Как использовать CRTL в устройстве Delphi в проекте C ++ Builder? (или ссылка на библиотеку выполнения C ++ Builder C)

StackOverflow https://stackoverflow.com/questions/5303568

  •  24-10-2019
  •  | 
  •  

Вопрос

У меня есть единица Delphi, которая статически связывает файл c .obj, используя {$L xxx} директива. Файл C составлен с компилятором командной строки C ++ Builder. Чтобы удовлетворить зависимости библиотеки библиотеки File C -файла (_assert, Memmove и т. Д.), Я включаю crtl Блок Аллен Бауэр упомянул здесь.

unit FooWrapper;

interface

implementation

uses
 Crtl; // Part of the Delphi RTL

{$L FooLib.obj}  // Compiled with "bcc32 -q -c foolib.c"

procedure Foo; cdecl; external;

end.

Если я собираю это устройство в проекте Delphi (.dproj), все работает правильно.

Если я собираю этот блок в проекте C ++ Builder (.cbproj), он не удается с ошибкой:

[ILINK32 Error] Fatal: Unable to open file 'CRTL.OBJ'

И действительно, нет crtl.obj Файл в папке установки Rad Studio. Есть .dcu, но нет .pas. Пытаясь добавить crtdbg к пункту «Использование» (заголовок C, где определяется _assert) дает ошибку, которую он не может найти crtdbg.dcu.

Если я удалю Использование пункт, вместо этого он терпит неудачу с ошибками, которые __assert а также _memmove не найдены.

Итак, в устройстве Delphi в проекте C ++ Builder, как я могу экспортировать функции из библиотеки времени выполнения C, чтобы они были доступны для связи?

Я уже знаю о Руди Вельтуисе статья. Анкет Я хотел бы избежать вручную писать обертки Delphi, если это возможно, так как они мне не нужны в Delphi, и C ++ Builder уже должен включать необходимые функции.

Редактировать

Для тех, кто хочет играть дома, код доступен в репозитории подрывной деятельности Abbrevia в https://tpabbrevia.svn.sourceforge.net/svnroot/tpabbrevia/trunk. Анкет Я принял совет Дэвида Хеффернана и добавил подразделение «Abcrtl.pas», которое имитирует CRTL.DCU при составлении в C ++ Builder. Это заставило работать поддержку PPMD, но библиотеки LZMA и Wavpack оба терпят неудачу с ошибками ссылки:

[ILINK32 Error] Error: Unresolved external '_beginthreadex' referenced from ABLZMA.OBJ
[ILINK32 Error] Error: Unresolved external 'sprintf' referenced from ABWAVPACK.OBJ
[ILINK32 Error] Error: Unresolved external 'strncmp' referenced from ABWAVPACK.OBJ
[ILINK32 Error] Error: Unresolved external '_ftol' referenced from ABWAVPACK.OBJ

Подобные, все они объявлены правильно, и _beginthreadex один фактически объявлен в ablzma.pas, поэтому он также используется компиляцией Pure Delphi.

Чтобы увидеть это самостоятельно, просто загрузите каталоги багажника (или просто «источник» и «пакеты»), отключите блок {$ ifdef bcb} внизу abdefine.inc и попытаться скомпилировать строитель C ++ «Аббревия .cbproj "Проект.

Это было полезно?

Решение

Мое мнение об этом в том, что вам нужно только подразделение Delphi в версии проекта Delphi.

В версии C ++ Builder вы только что скомпилируете и связываете Buldib.c, как будто это был файл C (он так!) В версии программы Delphi вы создаете .obj с BCC32, используйте CTRL и т. Д. Как описано.

Почему вы хотите завершить библиотеку C в обертке Delphi, которая будет употреблена в C ++?

Редактировать 1

Вы добавили разъяснения в комментариях.

Другой вариант, который нужно рассмотреть, - избежать CRTL и реализации пропущенных функций в FOOWRAPPER. Я делаю это так, а не использую CRTL, потому что это дает мне больше контроля, и я понимаю, что называется. Например, я не хочу никаких звонков printf() Протекает в мое приложение GUI или в мой DLL.

Это может быть привлекательным вариантом, если вам не хватает только нескольких функций. Часто самый аккуратный способ получить их - это связать их с msvcrt.dll, который является стандартным системным компонентом в наши дни. Конечно, это кажется немного тяжелым, чтобы связать в msvcrt.dll, просто чтобы получить memset(), memcpy() и т.п.

Сколько отсутствующих функций, когда вы компилируете блок Delphi без CRTL?

Редактировать 2

Я добавляю это в ответ, чтобы показать какой -то код. Из моей собственной кодовой базы я предлагаю это:

const
  __turboFloat: Longint=0;
  (* We don't actually know the type but it is 4 bytes long and initialised to zero.  This can be determined
     using tdump initcvt.obj.  It doesn't actually matter how we define this since it is ultimately not
     referred to and is stripped from the executable by the linker. *)

За ftol Я ссылаюсь на ftol.obj, который, как я предполагаю, я извлекал из одного из файлов LIB в компиляторе BCC55, который я использую.

Я думаю strncmp Должен быть довольно обычной реализацией в простом Паскале.

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

Честно говоря, я думаю, что «msvcrt.dll» выглядит довольно привлекательно!

Редактировать 3

Я скоро поговорил? Вы можете получить совершенно удобный sprintf вне пользователя32.dll, который почти все процессы загрузились в любом случае. Убедитесь, что вы выбрали wsprintfA Если это версия ANSI, вам нужна.

Редактировать 4

я заметил _beginthreadex. Анкет Вы говорите, что это определено в другом устройстве Delphi. Чтобы заставить компилятора увидеть его, вам нужно восстановить его в abctrl.pas, а оттуда вызовите реальную версию в ablzma.pas.

Когда вы включаете .obj в файл Delphi .pas, компилятор должен иметь возможность разрешить все ссылки в файле .obj из устройства Delphi, который ссылается на .obj. Вся эта игра рассматривается компилятором, а не линкером.

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

Другие советы

В этом случае предполагается, что функции, которые вы заинтересованы, доступны непосредственно из CRTL, поэтому выделение линкера с фиктивным (пустым) файлом OBJ, который должен работать, так как он удовлетворит линкеров, ищущий файл OBJ, который Delphi сказал ему Вам нужно, но все же найти функции в RTL.

Поздно, но более полное: crtl.dcu работает без проблем с D2005 до XE2.

Для D6 и D7 существует зависимость от midaslib.dcu. Ну, не совсем, DCU распределен с пунктом Dirty Issing.

Для D6 и D7 вы должны создать пустой суррогат midaslib.pas, например:

unit midaslib;
interface
implementation
end.

Теперь вы можете использовать crtl.dcu без внутренних ошибок!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top