Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 5
×

Создание С\C++ API для библиотек на С++

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Добрый день!

Хочу рассказать о своем open-source проекте, посвященному сабжу.
Для этого пилю beautiful capi — github.com/...​etrPPetrov/beautiful-capi

Ключевые особенности:
— Распилка всех классов на С функции, потом сборка этих С функций в класс заново в header only style клиенте.
Как результат клиент может использовать как С, так и С++ API
— Нет QueryInterface, как в COM-подобных системах, но зато есть down_cast<>() — это фактически dynamic_cast, однако обработка на стороне библиотеки, чтобы не было проблем с бинарной несовместимостью RTTI.
Из-за этого библиотека может быть на MSVC 2019, а клиент на Borland C++ compiler или Digital Mars C++ compiler.
— Вся аллокация\деаллокация идет на стороне библиотеки, чтобы не было проблем с разными менеджерами хипов
— Экспортируемые С функции имеют простые, понятные имена. Вместо знаков кракозябров (@!? и прочих), используется только знак подчеркивания (_). Правило такое: сначала идет имя неймспейса (переведенное в snake_case),
затем добавляется имя класса (переведенное в snake_case), и имя метода в этом же стиле. Например, метод Show класса Printer неймспейса Hello будет иметь имя hello_printer_show.
— Решается проблема с исключениями. Библиотка ловит свои исключения, а затем передает информацию о них через специальную структуру (первій аргумент в С функциях). На клиенте исключение повторно вібрасівается. Поддерживается иерархия исключений.

Уже сейчас при помощи инструмента bcapi можно создавать DLL-ки (и SO-шки, и DYLIB), которіе имеют С API, и к єтому API есть набор сгенерированніх .h файлов с враппер классами на С++. Создавать DLL можно при помощи последней версии студии, например, Visual Studio 2019 и использовать все возможности новіх стандартов С++ (С++ 17, С++11). А использовать это DLL при помощи хоть Visual Studio 6.0. Если рантайм использовать статический (ключик /MT) — то такая DLL будет зависить только от kernel32.dll и все, больше никаких зависимостей не будет.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

У тебе мішанина в опису проекта на гітхабі (та й у цій темі?) C і C++.

Це різні мови. Будь ласка, люди, припиніть писати C/C++.

Та чим вони різні? С то є сабсет С++, і кожен, хто пише на С++, може певною мірою читати С.

Сучасний C++ не є сабсетом C. І з читанням C реальних проектів у сучасних «плюсовиків» бувають, на жаль, складнощі.

Ваше твердження було б правдиве якби це відбувалося бозна кілько років тому, коли існував лише той самий C++, котрий називали «С with classes».

Але взагалі то не важливо. Важливо те, що коли пишуть C/C++ то практично завжди забувають про C незалежно від контексту. Чи можу я скористатись вашим проектом, ПЗ, та й будь чим не торкаючись C++ _взагалі_? Таких проектів повно і це сумно.

Що саме сумно? Що люди обирають ту мову чи сабсет, котрий їм зручніше використовувати для їх проекта?

Сумно бачити вживання наступного сполучення: «C/++»

Бо це різні мови. Не одразу зрозуміло що маєтьс на увазі під «/». Сполучник «і» чи «або»?

Коли це просто сполучник це ще непоганий випадок. А в описах вакансій від рекрутерів буває бозна що :D

це різні мови.

я би добавив, різний стиль мислення (mindset)

Вам пишуть

С то є сабсет С++

Ви відповідаєте

C++ не є сабсетом C

Це трохи різні твердження. Якщо не брати нові можливості як-то ініціалізация масивів та структур, restrict та масиви на стеку, то C є сабсет C++.

Якщо брати твердження, що з читанням C є складнощі, то взагалі С++ це дуже велика мова, можливо у кого-сь будуть складнощі читати шаблони а-ля boost, думаю можна знайти інши приклади у межах лише С++.

Перепрошую, не так відповів. Дійсно, то трохи різні твердження.

Але основну суть моєї думки я не змінив — це різні мови і не варто вживати «C/C++».

Це особливо яскраво виражається коли приходить людина яка працює лише з C, але не хоче взагалі торкатися «С++».

То знайдіть їй відповідний кусок роботи.
Чи вже прийшов час програмістами розкидатись?

Я повторюю, що С++ мова дуже велика, тому ситуацію, коли людина не хоче торкатися якусь газузь можна знайти навіть не перестрибуючі з С на С++. Наприклад, проргаміт C, який писав модулі для nginx, може не захотіти писати драйвери Linux та firmware. Навпаки такод працює. Якщо програміст писав багато математики на C++, то він не захотіти торкатися GUI на QT. Тому, як на мене, межа C/C++ досить умовна, бо у вередині С (в меньшій мірі) та С++ (трохи в більший) можна знайти також багато подібних ситуацій.

Наприклад, проргаміт C, який писав модулі для nginx, може не захотіти писати драйвери Linux та firmware

Чому? І nginx і модулі для linux і драйвери і firmware найчастіше пишуться на C, а «захотів чи не захотів» то вже особиста справа людини.

Тому, як на мене, межа C/C++ досить умовна

У вас можливо й так. У мене, на жаль, зовсім інший досвід. Можливо мені не пощастило з нормальними проектами на C++? Хтозна...

Знову ж таки, підкреслюю, то всього-лиш думка. Залежно від контексту може змінюватися її актуальність.

sizeof(’c’), рекурсивний виклик main, обов’язкова наявність прототипів у с++, різна семантика прототипу з пустим списком аргументів, auto

я вам відповів чим вони різні. і думаю це не вичерпний перелік. хоч 0,00001% — це вже не сабсет

В С типізація щодо вказівників менш прискіплива, через це купа С коду не скомпілиться як С++.

Де мішанина? Все корректно.В якой конкрентной пропозиції?

Чапи создает два программных интрерфейса для С++ библиотеки, один API — это чистый С API, другой это С++ API. Билииотека на С++ может быть скомпилированна с использованием самых последних стандартов С++, например, С++ 17. Однако клиент может быть на чистом С. Еще клиентом такой библиотеки может быть старый компилятор С++, который, допустим, не поддерживает С++ 11. Поэтому я и написал С\С++, имея в виду, что и «С» и «С++».

Дякую, таке пояснення вносить більше ясності «що до чого».

Хочу також запитати. Чи правильно я вас розумію

1) Я маю чиюсь бібліотеку що написана на C++
2) За допомогою вашого софту я отримую API яке можу застосовувати в чистому C коді, який я буду спокійно білдити з —std=c99 або —std=gnu99?

Якщо так то це просто прекрасно! Можна буде працювати з Qt без плюсів!

Можна буде працювати з Qt без плюсів!

Навіщо???

Після проектів на яких довелося працювати у минулому у мене розвилась плюсофобія, тепер запобігаю їх будь-яким чином і намагаюсь забути як страшний сон.

Це особисте, давайте в це не поглиблюватися.

Таки да. Вот основная проблема в чапи — это то, что описание API создается вручную. Однако, делать описание API вручную — намного легче, чем делать обертки вручную. У меня была даже идея самому обернуть весь QT API. И даже есть репозиторий для єтого на гитхабе, где я начинал. Хотя вам не обязательно делать описание для всего QT API, можно только для необходимого минимума, необходимого вам.

Дуже вдячний вам за розгорнуті відповіді!

Не знаю чому, але без ваших коментарів я чомусь не одразу зрозумів що саме робить проект.

Під час дозвілля спробую скористатись.

Вот только сейчас подумал, что там же есть moc генератор. И он на вход берет какой-то С++ header файл и генерирует код. Для обработки там сигналов и прочее. Вот думаю, тут может біть проблема.

Как-то загадками пишете. Современніе компиляторы — имеете в виду clang с его AST API? А что «юзалось» во времена gcc 2.95?

А (зевая).... Я изначально ушел от парсинга С++, чтобы не замарочиваться с этим. Нужно было проект завершить достаточно быстро. А так — в планах есть завершение clang обертки над bcapi — github.com/PetrPPetrov/clang-bcapi

Шобы было? Я думал чувак новый GUI под плюсы запилил, а тут академичка под 2019 студию. Пользователю пофиг на каком плюсовом стандарте будет собрана длл, а бы работала.

Если библиотека использует С++11\С++14 то не пофиг. Пользователь, у которого старій компилятор (по корпоративнім, скажем, соображениям) — то пользоваться такой библиотекой ему не получится. Или, скажем, на Linux, если библиотека даже не использует С++11, а была собрана при помощи флага stdc=c++11, то такую библиотеку нельзя загрузить в окружение не-С++11. И наоборот. Еще, скажем, если вы продаете коммерческую библиотеку с закрытым исходным кодом корпоративному пользователю (то есть другим софтовым фирмам), то готовтесь собирать такую библиотеку под весь зоопарк компиляторов. Версий студий начиная с 6.0, 2003, 2005, 2008, 2010, 2012, 2013, 2015, 2017, 2019, Borland C++, GCC, Clang, Digital Mars C++. И вот если вы используетет С++ 11 в библиотеки то у вас проблемы. Вы не сможете ее собрать, если компилятор клиенте не поддерживает его.Поэтому на помощь приходит bcapi. Вообще, bcapi был вдохновлен ESRI PE Library — вот ее API — help.arcgis.com/...​/geometry/geometry.htm#PE чтобы не ручками создавать эти С функции, а при помощи скрипта. Внутри за этими функциями скрыты класса\объекты. Плюс еще чтобы у клиента была использовать эти С функции в качестве С++ интерфейса bcapi генерирует С++ врапперы для таких С функций.

мне (не знакомому с рынком платных библиотек) кажется, что этот рынок делится на 2 части:
1) крупные игроки, которые давно решили для себя эту проблему, так как уже давно крупные игроки
2) стартапы, которые будут ориентироваться на новых клиентов с новыми компиляторами
ну и вообще, рынок платных библиотек умирает под гнетом опен-сорса и saas

Отчасти вы правы. Однако таких решений существует множество, начиная от Microsoft COM technology (довольно тяжеловесной), и всякими «проссплатформенными COM» (то же довольно тяжеловесными). Крупные производители библиотек — поддерживают все необходимые компиляторы — но для это трудоемко. Часто бывает видишь, что фирма — солидная, а вот библиотеку поддерживают для, скажем, MSVC 2012+, а старые «не поддерживаются». Однако проблема в самом С++ — нет стандартного ABI для С++. Хотя сейчас пытаются ввести «модули» в последний страндарт С++ — но еще не доделали. Проект bcapi в основном для старапов. Хотя бівает, что и старпапы имеют в качестве клиентов большие копрорации у которых «старые компиляторы» — вот тут и область применения bcapi.

Ну стартап может «ручками» написать extern «C» интерфейс на библиотеку и сразу все проблемы решаются навсегда. Если крупный клиент, который платит.

COM — сделан для кровавого и не очень энтерпрайза, чтобы сшивать модули разных вендоров вместе, в том числе — через сеть.

Вообще — Вам виднее, я в другой области работаю.

bcapi — єто пратически и есть «ручками» написать extern «C» — только при помощи Python скрипта, чтобы не сильно много было писать ручками.

Тут имеется в виду «пользователь» — єто не пользователь ПК, а «пользователь
библиотеки». Пользователь библиотеки — єто такой же программист, но которій ей пользуется, а не разрабатівает, поєтому и «пользователь».

эталонное ненужно

Note it does not parse the library source code to obtain its API description. Instead of that, as author you should provide a library API description in XML format.

лол

Тоже ожидал clang под капотом, но никак не XML...

Підписатись на коментарі