Lazarus (GUI) + C++ (engine)
Модератор: Модераторы
Lazarus (GUI) + C++ (engine)
Здравствуйте. Есть некоторые функции хорошо написана на С++ (парсер документа) переписывать которые нет возможности, и есть кросплатформенное визуальное приложение на Lazarus, в которое эти функции необходимо добавить. Подскажите, как правильно интегрировать С++ код в проект на Lazarus? Может есть какой то вариант вставок с++ кода с подключением внешнего компилятора? Если использовать библиотеки, то как это делать правильно?
- Снег Север
- долгожитель
- Сообщения: 3071
- Зарегистрирован: 27.11.2007 15:14:47
- Контактная информация:
Насколько я знаю, нет способа внедрить С++ код в проект на Lazarus. Единственное, что приходит в голову - сделать на С++ dll с интерфейсом, совместимым с вызовами на FPC.
Снег Север писал(а):Насколько я знаю, нет способа внедрить С++ код в проект на Lazarus. Единственное, что приходит в голову - сделать на С++ dll с интерфейсом, совместимым с вызовами на FPC.
если C-обёртку написать, можно компоновать С++ код, без dll.
Снег Север писал(а):Насколько я знаю, нет способа внедрить С++ код в проект на Lazarus. Единственное, что приходит в голову - сделать на С++ dll с интерфейсом, совместимым с вызовами на FPC.
Правильно ли я понимаю, что через библиотеку я смогу иметь только доступ к функциям (не объектам), которые возвращают данные в одинаковых с паскаль типах?
Добавлено спустя 1 минуту 35 секунд:
скалогрыз писал(а):если C-обёртку написать, можно компоновать С++ код, без dll.
Как это может выглядеть на практике?
CRobin писал(а):Как это может выглядеть на практике?
в С++ есть такая конструкция:
Код: Выделить всё
extern "C" {
...
}
что позволяет обращаться к функциям С++ точно так же как и к функциям С.
(здесь, здесь)
соответственно есть определённые ограничения, например обращатся к полям/методам С++ класса не получится. Зато можно сделать для них обёртки, в виде Си-шных функций.
скалогрыз а сишные функции как вставить в Lazarus?
CRobin писал(а):скалогрыз а сишные функции как вставить в Lazarus?
функция описывается как внешняя (с уважением её соглашения вызова, который обычно cdecl для Си-шных статический библиотек, либо stdcall, если загружается через .dll). Внешние функции легко опознать по ключевому слову "external".
Например так:
Код: Выделить всё
{$L deflate.o} // Объектный файл с функцией
function deflate(var strm: z_stream; flush: cint): cint; cdecl; external;
в это случае функция будет находится по имени "deflate" (а точнее по имени "_deflate")
и в Си++ она должна быть описана так
Код: Выделить всё
extern "C" {
int deflate(z_stream * strm, int fluch)
{
....
}
}
Ну или если через .dll то так:
Код: Выделить всё
const
libz='zlib1';
function deflate(var strm: z_stream; flush: cint): cint; stdcall; external libz name 'deflate';
Кстати, не факт, что в .dll будет использоваться stdcall, но по-умолчанию имеено он.
Важное отличие что после слова external идёт строковая константа, с указанием имени динамической библиотеки.
Статическая/динамическая линковка Си/Си++ кода используется в Delphi/FPC на каждом шагу, где критична скорость/существующая библиотека.
Например, zlib или libjpeg имеют реализации на чистом паскале, но уступают в производительсности Си-шным, по-этому обычно используют си-шные библиотеки.
И ДА! важно помнить, что Си, скомпилированный в Visual Studio к паскалю не скомпонуется СТАТИЧЕСКИЙ, и нужно использовать GnuC (например в составе MinGW). А всё потому что формат объектных файлов разных.
Зато проблем с .dll скомпилированныйм с помощью Visual Studio быть недолжно, ибо стандарт.
Чем практически отличается dll от объектного файла, если оба требуют предварительной компиляции?
CRobin писал(а):Чем практически отличается dll от объектного файла, если оба требуют предварительной компиляции?
.dll это внешний файл, который должен будет распространятся с исполняемым файлом.
А объектный файл будет скомпонован в исполняемый файл.
Скажите, я правильно понимаю что в обоих случаях в модуле/библиотеке С++ могут быть только функции (флэт апи)? Глобальных переменных, в которых хранятся внутренние состояния там быть не может?
CRobin писал(а):Скажите, я правильно понимаю что в обоих случаях в модуле/библиотеке С++ могут быть только функции (флэт апи)? Глобальных переменных, в которых хранятся внутренние состояния там быть не может?
могут. Но если ты хочешь к ним доступ получить из паскаль программы, то лучше предоставить соответствующие функции.
Я даже классы через DLL передавал ...
(В основной программе делал точно такой же класс но с абстрактными методами, а в DLL функцию которая возвращала ссылку на экземпляр класса которую я благополучно присваивал переменной "абстрактного класса" ... )
(В основной программе делал точно такой же класс но с абстрактными методами, а в DLL функцию которая возвращала ссылку на экземпляр класса которую я благополучно присваивал переменной "абстрактного класса" ... )
Последний раз редактировалось Alex2013 14.02.2021 07:45:52, всего редактировалось 1 раз.
Alex2013 писал(а):Я даже классы через DLL передавал ...
(В основной программе делал точно такой же класс но с абстрактными методами, а в DLL функцию которая возвращала ссылку на экземпляр класса
которую я благополучно присваивал переменной "абстрактного класса" ... )
речь идёт о Си++ классе?
Нет, DLL писал в Дельфи использовал в Лазарусе и ХайАсме .
Но думаю что попробовать при совпадении типов можно ... впрочем едва-ли ... разве что Си будет "борландовского" разлива .
Но думаю что попробовать при совпадении типов можно ... впрочем едва-ли ... разве что Си будет "борландовского" разлива .
Alex2013 писал(а):Нет, DLL писал в Дельфи использовал в Лазарусе .
Но думаю что попробовать при совпадении типов можно
не рекомендую рисковать.
Частный случай может заработать... а вот когда дело дойдёт до проблем, то окажется что придётся переписывать всё с нуля.
Если делать решение для винды, и нужны объекты, я бы рекомендовал использовать COM-интерфейсы.
Если нужна кроссплатформенность, то Си-подобные обёртки.
OpenGL-ом же все пользуются, и ничего! Си API вполне всех устраивает.
Или Gtk. В своём ядре это Си++, а снаружи это Си.
