LINUX.ORG.RU

Покритикуйте способ подключения плагинов в си

 ,


0

1

Написал такой код: https://github.com/codemeow/cpluginconnector

Делает такую вещь - существует ряд плагинов, которые регистрируются у менеджера, потом при вызове парсера (который может быть вызван при чтении файла, в данный момент имитируется прямым вызовом) инициируется нужный плагин. У себя такую вещь собирался прикрутить для разбора extended-ini файлов.

git clone https://github.com/codemeow/cpluginconnector.git

Ну или https://github.com/codemeow/cpluginconnector/archive/master.zip

Покритикуйте, пожалуйста. Пулл реквесты или хотя бы куски кода здесь приветствуются.

Собирать можно как прямой компиляцией а потом линковкой, так и

qmake plugin.pro && make && ./plugin

★★

Последнее исправление: cetjs2 (всего исправлений: 2)

1) ты бы хоть вкратце описал, чего сделал. А то в куче кода лень разбираться.

2) на кой тебе qmake в сишном проекте? Ужаснафиг!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

1) ты бы хоть вкратце описал, чего сделал. А то в куче кода лень разбираться.

Дак описал же. Показывает принцип механизма подключения плагинов. Кто-то читает из файла инструкцию и вместо огромного свича просто посылает эту инструкцию на выполнение тому плагину, который ее умеет.

2) на кой тебе qmake в сишном проекте? Ужаснафиг!

Под шидой в консоли сидеть не комильфо.

sambist ★★
() автор топика
Ответ на: комментарий от sambist

Под шидой в консоли сидеть не комильфо.

Зря ты это сказал... Эдику :) (Видел этот тред на одной странице)

slackwarrior ★★★★★
()
Ответ на: комментарий от sambist

П.С. Отдельно сомневаюсь, что Эдик скажет по теме, но вот за qmake он сейчас из тебя душу будет вынимать долго и с удовольствием.

slackwarrior ★★★★★
()
Ответ на: комментарий от sambist

Кто-то читает из файла инструкцию и вместо огромного свича просто посылает эту инструкцию на выполнение тому плагину, который ее умеет.

Ничего не понял.

Под шидой в консоли

Ужас!

Ну дык cmake же есть. И в мастдайке, и в линуксе работает. Зачем тебе культяшный огрызок?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от slackwarrior

По теме мог бы сказать "ненужно" или "сделай по-другому" (и, возможно, предложил бы вариант). Но я не могу понять, что эта штукенция вообще делает. И зачем это надо. Может и правда "ненужно"?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Ну дык cmake же есть. И в мастдайке, и в линуксе работает. Зачем тебе культяшный огрызок?

В мастдайке и баш работает - зачем цмэйк, порождение культистов NIH :)

slackwarrior ★★★★★
()
Ответ на: комментарий от Eddy_Em

Ничего не понял.

Эдик, что ты сегодня принимал?

[Alpha]
param1 = 5
param2 = 6

[Beta]
param1 = 12.0
param2 = 9
param3 = 9
param4 = 9
param5 = 9
param6 = 9

Вот у тебя инишник. Чтобы парсить его конечным автоматом тебе нужен офигенно большой свич там, где ты получаешь имя параметра. А завтра ты добавишь секцию [Gamma] и у тебя все развалится нахрен. Я предлагаю метод расширения функционала через подключение плагинов. Есть плагин для парсинга секции [Alpha], секции [Beta], можешь хоть сейчас написать плагин для секции [Gamma]. Вызовешь фунцию initgamma() и можешь больше ничего не делать.

sambist ★★
() автор топика
Ответ на: комментарий от Eddy_Em

Сказали ж тебе «плугины». Предложи вариант плугинов штоле. (От себя могу предложить аффтару посмотреть в сторону «локатора служб/ресурсов» и определиться, что у него там (я вижу «манагер плугинов», а в коде «хэши и вэлью» - может для этого проще заюзать noSQL-ную базу?))

slackwarrior ★★★★★
()
Ответ на: комментарий от anonymous

Я теги сарказм не ставлю (цмейком сам пользуюсь :))

slackwarrior ★★★★★
()
Ответ на: комментарий от slackwarrior

может для этого проще заюзать noSQL-ную базу?))

SQL в embedded не засунешь, хеши здесь только чтобы делать switch по строкам.

sambist ★★
() автор топика
Ответ на: комментарий от sambist

SQL в embedded не засунешь

ну тогда хотя бы тег про эмбеддед не помешал бы в оформлении темы

slackwarrior ★★★★★
()

А действительно ли они плагины? Ты их подключаешь не во время исполнения, и даже не во время компиляции, а прямо в исходниках, причём явно вызываешь инициализаторы. Это скорее модули, а не плагины.

i-rinat ★★★★★
()
Ответ на: комментарий от sambist

в случае именно инишника идея плохая. в общем случае идея хорошая — но только для относительно больших проприетарных приложений с длительной поддержкой.

next_time ★★★★★
()
Ответ на: комментарий от next_time

в случае именно инишника идея плохая.

Вообще изначально задумал эту вещь для своего проекта, у меня там extended-ini вот такой:

# Project: Smilo project
# Theme name: Default
# File: Button, normal state
# Last edit: 26 January 2014

# Background
[tetragon]

flg = (1, 0)

pt1 = (    0,     0)
pt2 = (W - 1,     0)
pt3 = (W - 1, H - 1)
pt4 = (    0, H - 1)

grc = (0, 0xD0D0D0)

# Button shadow
[tetragon]

flg = (1, 1)

pt1 = (    0,     0)
pt2 = (W - 1,     0)
pt3 = (W - 1, H - 1)
pt4 = (    0, H - 1)

rn1 = (5, 5)
rn2 = (5, 5)
rn3 = (5, 5)
rn4 = (5, 5)

grc = (0, 0xCBCBCB)

# Button border
[tetragon]

pt1 = (    1,     1)
pt2 = (W - 2,     1)
pt3 = (W - 2, H - 2)
pt4 = (    1, H - 2)

rn1 = (2, 2)
rn2 = (2, 2)
rn3 = (2, 2)
rn4 = (2, 2)

grt = (1, 1)
gp2 = (0, H)

grc = (0, 0xADADAD), (M, 0x7D7D7D)

# Fill
[tetragon]

flg = (1, 0)

pt1 = (    2,     2)
pt2 = (W - 3,     2)
pt3 = (W - 3, H - 3)
pt4 = (    2, H - 3)

grt = (1, 1)
gp2 = (0, H)

grc = (0, 0xF2F2F2), (M, 0xD5D5D5)

# Left inner white shadow
[segment]

pt1 = (2,     2)
pt2 = (2, H - 4)

grt = (1, 1)
gp2 = (0, H)
grc = (0, 0xF7F7F7), (M, 0xEEEEEE)

# Top inner white shadow
[segment]

pt1 = (3,     2)
pt2 = (W - 4, 2)

grc = (0, 0xFAFAFA)

# Right inner white shadow
[segment]

pt1 = (W - 3,     2)
pt2 = (W - 3, H - 4)

grt = (1, 1)
gp2 = (0, H)
grc = (0, 0xF7F7F7), (M, 0xEEEEEE)

Мне было бы очень удобно для графических примитивов сделать отдельные модули, нежели все держать в многокилометровом свиче.

sambist ★★
() автор топика
Ответ на: комментарий от sambist

Попробуй делать вот так:

static void
__attribute__((constructor))
initalpha(void)
{

Тогда в основном модуле не нужно будет инклюдить «plugins/alpha.h» и вызывать initalpha(). Просто во время компиляции добавляешь свой alpha.c к списку компилируемых.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Я думал про этот ваш #pragma start\exit, но проблема в несовместимости между компиляторами. Если тянут это в embedded - то там вообще тихий ужас.

И да, отказался еще и потому, что до main'а и до инита этих плагинов нужен будет инит регистратора. А в ините регистратора может понадобится еще что-то. Ну нафиг этот инициализатор.

sambist ★★
() автор топика
Ответ на: комментарий от sambist

многокилометровом свиче.

если структура каждой секции одинакова, то никакого многокилометрового свича и не будет, можно обойтись одной, достаточно универсальной ф-ей. а вот если там что-то сложное, то да, своего рода система модулей (а не плагинов), как писал оратор выше.

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

next_time ★★★★★
()
Ответ на: комментарий от next_time

если структура каждой секции одинакова, то никакого многокилометрового свича и не будет

Они там, как раз таки разные. И по размеру и по типам данных.

sambist ★★
() автор топика
Ответ на: комментарий от slackwarrior

cmake нужен для безболезненной сборки чего-то, имеющего 100500 зависимостей. Потому как вручную Makefile ты не напишешь, чтобы он тесты делал и нужные библиотеки искал. А autotools — говно.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от sambist

Имхо, под структурой имеется в виду способ обработки секций: он у тебя везде один, ини-файл, параметр=значение (тут в минимальном варианте достаточно сплита в цикле... Что знаем - берем, что не знаем - игнорим). Обычно плугины имеют смысл, если пристегивается конфиг, который непонятно как разбирать готовым парсером, т.к. структура разметки допускает значительные «вольности» (например, кастомный XML), а внутре стоит валидатор, который не пропускает «неправильные секции». А вот если находит ссылку на обработчик - передает обработку ему. Если просто надо добавить новые пары ключ-значение - это можно делать и старым обработчиком (все равно их смысл будет парсить какой-то новый код)

slackwarrior ★★★★★
()
Ответ на: комментарий от Eddy_Em

Эдик, в твоем внутреннем капитане я никогда не сомневался :) Давай за плугины чего-нибудь, а?

slackwarrior ★★★★★
()
Ответ на: комментарий от sambist

Чтобы парсить его конечным автоматом тебе нужен офигенно большой свич там, где ты получаешь имя параметра.

Согласен (вспомнил, как подобные хрени когда-то делал; да и с JSON не лучше ситуация). Но: можно упростить этот «большой свич», если строить дерево не вида Ключ → {{параметр, значение}, ...}, а брать хэши от имен параметров и дерево строить вида Ключ → {{хэш, параметр, значение}, ...}. В этом случае тебе не нужно будет делать strcmp в каждой ветке if'а, а сделать реальный switch с числами. А случаи совпадения хэшей разных имен просто обрабатывать по заранее подготовленной структуре.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

а брать хэши от имен параметров и дерево строить вида Ключ → {{хэш, параметр, значение}, ...}. В этом случае тебе не нужно будет делать strcmp в каждой ветке if'а, а сделать реальный switch с числами. А случаи совпадения хэшей разных имен просто обрабатывать по заранее подготовленной структуре.

Эдик. Ты не поверишь.

sambist ★★
() автор топика
Ответ на: комментарий от sambist

Есть плагин для парсинга секции [Alpha], секции [Beta]

А, теперь дошло: ты предлагаешь не одной программкой парсить, а кучей отдельных бинарей.

Т.е. при запуске основной ты читаешь из конфига доступные «плагины», затем если в другом конфиге натыкаешься на секцию, ищешь, какой «плагин» ее обрабатывает. Если такой «плагин» есть, то ты делаешь dlopen и обрабатываешь.

Да, удобно, если хреньку разрабатывает много людей и они не хотят общий код засирать.

Принимай мое «нужно».

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от slackwarrior

Если просто надо добавить новые пары ключ-значение - это можно делать и старым обработчиком (все равно их смысл будет парсить какой-то новый код)

Вопрос в том, что ключ-значения зачатую уникальны для большинства секций. В моем примере не было секции [labe], там строковый text, парные вычисляемые pt1\2, ну и т.д.

sambist ★★
() автор топика
Ответ на: комментарий от Eddy_Em

А, теперь дошло: ты предлагаешь не одной программкой парсить, а кучей отдельных бинарей.

Не дошло. Бинарь один, плагины-модули вшиты внутрь.

sambist ★★
() автор топика
Ответ на: комментарий от Eddy_Em

Потому как вручную Makefile ты не напишешь, чтобы он тесты делал и нужные библиотеки искал.

П.С. идея как всегда замечательная и с претензией на «серебряную пулю», только... чаще приходится писать модули для поиска этих нужных библиотек. Да и новые системы сборки до/после/вместо цмейка пиать никто не перестал (scons, jam, далее везде... А если взять жабу - еще интереснее: жили-были nat, maven, ivy... А потом им всем настали грабле «берущие лучшее от всех сразу» (и недостатки от всех сразу тоже, плюс новые, но об этом они не расскажут))

slackwarrior ★★★★★
()
Ответ на: комментарий от slackwarrior

Предложи вариант плугинов штоле

я знаю 2 варианта: а) через dlopen, б) через popen, в) через fork & system со взаимодействием через IPC.

Вроде все.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

да и с JSON не лучше ситуация

если писать парсер каждый раз на коленке, а потом через год сталкиваться с проблемой расширения - безусловно :)

slackwarrior ★★★★★
()
Ответ на: комментарий от sambist

тогда лови мое «ненужно»!

Это нихрена не плагины. И даже не модули. Это тупо раскидывание исходного кода по файлам.

Чушь.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от slackwarrior

Я еще не сталкивался с тем, чтобы cmake'а мне не хватило. А уж если ты с кудой работаешь, то cmake вообще рвет.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от slackwarrior

Посмотри, например, что такое плагины deadbeef. Вот то — действительно плагины.

А с so-шкой элементарно: ты документируешь интерфейс, т.е. пользователю нужно забульбенить определенную функцию, которая будет вызываться для обработки данной секции файла. Она распарсит параметры-значения и выполнит какую-то определенную работу. Ну и вернет какие-то данные.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Я еще не сталкивался с тем, чтобы cmake'а мне не хватило.

Ты либо кодишь под старые версии либ, либо под один дистр, где все всегда лежит на тех же местах :)

slackwarrior ★★★★★
()
Ответ на: комментарий от slackwarrior

А с какого перепугу cmake должен не найти библиотеку? Единственный вариант — библиотека самопальная, и ты не позаботился о pkg-config. Но тогда ты и на своем компе эту шнягу не скомпиляешь, пока cmake'овский модуль не напишешь (а вообще, проще написать короткий файлик для pkg-config).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Попробуй SDL2 с сорцов собери при помощи цмейк с нужными ключами (в дистрах обычно SDL, собранный как левая пятка мантейнеров захотела) или xerces-c и openssl нужной версии найди «искаропки» цмейком, а потом разговаривай.

slackwarrior ★★★★★
()
Ответ на: комментарий от Eddy_Em

Подходит, когда плугинов мало и функционал даже теоретически не пересекается. (Например, ты автор и системы плугинов и плугинов... Но... зачем тогда тебе плугины? :)))

«Но мы пойдем глубже» (с)

Пользователь вообще может ничего не знать, «How do I shot web?» (c)как именно он парсит параметры (об этом позаботится автор другого плугина) :) А еще он не обязан знать, какую so-шку ему надо загрузить, чтоб распарсить чего-то (он может постучаться к манагеру плугинов, а тот ему предоставит интерфейс, который подписался реализовать анонимныйсторонний автор плугина для разбора параметров :))

slackwarrior ★★★★★
()

Подключать через механизмы RPC.

invy ★★★★★
()
Ответ на: комментарий от slackwarrior

Попробуй SDL2

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

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Мне эта какашка не нужна.
И да, если погроммист — рукожопый индюк

Проецируешь? А ответь на вопрос с засыпкой... Зачем в цмейке модули вообще? Че он искаропки находит не все и не всегда (от дистра к дистру и от версии к версии)?

slackwarrior ★★★★★
()
Последнее исправление: slackwarrior (всего исправлений: 1)
Ответ на: комментарий от slackwarrior

Зачем в цмейке модули вообще?

Затем, что если бы все программисты были нормальными, а не так, что большинство — рукожопы, то хватило бы за глаза тупо pkg-config, а из cmake'овских фич использовался бы лишь удобный подход к install/uninstall (кстати, в cmake нет умолчательной uninstall секции, ее надо самому городить), тестам в предкомпиляционное время (скажем, чтобы выставить нужные ключи в соответствии с твоим железом) и еще кое-что.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Затем, что если бы все программисты были нормальными, а не так, что большинство — рукожопы, то хватило бы за глаза тупо pkg-config

А вот х*й ты угадал. Затем, что программисты цмейка зае*лись зоопарком опенсорцных либ - у них и так полно забот с зоопарком компиляторов (и отдельно - инициативами леннартов переложить стандартные диры куда-нибудь КЕМ, потому что гладиолус) - и чтоб ты, пользователь цмейка сам писал модули для своих зависимостей (ниасилел-нинужно? дадад), потому что никакой pkg-config тебя не спасет от протухших версий, заброшенных мантейнерами пакетов, и «слишком новых» библиотек и тэ-дэ.

slackwarrior ★★★★★
()
Ответ на: комментарий от Eddy_Em

Вот почему я до сих пор свою обертку getopt'а не оптимизировал?

Может, потому, что оно только 1 раз на старте программы запускается и совершенно никого не напрягает, обработаются аргументы за 1мс или за 100мс?

Eddy_Em ☆☆☆☆☆
()

не совсем понятно где ты тут плагины нашел. обычные модули с общим интерфейсом.

waker ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.