Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Исходники vs dll


Автор: borisbn 10.2.2012, 20:39
Надеюсь, что ни у кого не возникает вопроса, нужно ли выносить законченный по логике код в отдельный модуль.
Вопрос в следующем - как оформлять этот модуль - в виде *.h + *.cpp или *.h + некий бинарник.
У "исходников" есть плюс - при изменении интерфейса компилятор заботится о соответствии версий.
Минус - необходимость перекомпилировать (при чём обязательная) всего проекта.
Плюс у "dll-ек" - легко подменять  реализацию без "уведомления" основной программы.
Минус - при изменении интерфейса бинарника может случиться ситуация - несоответствия h-ников dll-кам...
В общем, надеюсь, вы поняли дилемму...
Вопрос как вы решаете эту дилемму 

Автор: vol4ek 10.2.2012, 20:48
По мне так динамическая загрузка dll довольно удобная штука.

Автор: newbee 10.2.2012, 21:28
Мысль едва уловима. Или логика. А может, обе...

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

Еще частой перекомпиляцией во время разработки можно избежать банально не так часто пересобирая программу. Накодил два часа - компилируешь, это помимо прочего еще позволяет больше сконцентрироваться на задаче, а не ловле синтаксических и прочих ошибок. У меня так не получается smile А вот бы было хорошо, если IDE могла держать в памяти рантайм разрабатываемой программы, разработчик написал функцию, скомпилировал одну ее, IDE загрузила ее в рантайм и играйся с ним сколько влезет. Прям как если бы разработка шла на нормальном языке.

Проголосовала за src, потому что это единственный вменяемый вариант из предложенных.

Автор: feodorv 11.2.2012, 01:27
Цитата(borisbn @  10.2.2012,  20:39 Найти цитируемый пост)
Минус - необходимость перекомпилировать (при чём обязательная) всего проекта.

Гм. Непонятно, почему "всего проекта". Если в коде что-то изменилось, чего хватает на изменение одной dll, то и перекомпилироваться будет область исходников, как бы соответствующая этой dll...
Кроме того, писать целый проект так, как будто его подчасти можно выделить в отдельные dll - хороший стиль программирования ;)

Автор: volatile 11.2.2012, 01:49
Цитата(feodorv @  11.2.2012,  01:27 Найти цитируемый пост)
Непонятно, почему "всего проекта". Если в коде что-то изменилось, чего хватает на изменение одной dll, то и перекомпилироваться будет область исходников, как бы соответствующая этой dll...

feodorv, я думаю 
borisbn, имел ввиду что при изменении участка кода , нужно будет перекомпилировать весь код, который от него зависит. (фактически весь проект)
При изменении длл, ничего перекомпилировать (кроме самой этой длл) не нужно. (при условии конечно, что ничего не поменялось в интерфейсе)

borisbn, для полноты картины, нужно бы еще добавить было статические библотеки.
Для себя, исходники, и статические либы. 
DLL практически для себя не использую. толко если одавать кому-то. (это не плод каких-то умных расчетов, просто так получается, не знаю почему  smile )
Проголосовал за исходники

Автор: vol4ek 11.2.2012, 01:52
Цитата(newbee @  10.2.2012,  21:28 Найти цитируемый пост)
Другое дело, если у тебя большой проект, некоторые его части можно выносить в библиотеку


это и имелось ввиду  smile

Добавлено через 1 минуту и 54 секунды
Цитата(volatile @  11.2.2012,  01:49 Найти цитируемый пост)
При изменении длл, ничего перекомпилировать (кроме самой этой длл) не нужно. (при условии конечно, что ничего не поменялось в интерфейсе)


чем не вариант

Автор: feodorv 11.2.2012, 02:40
Цитата(volatile @  11.2.2012,  01:49 Найти цитируемый пост)
(фактически весь проект)...(при условии конечно, что ничего не поменялось в интерфейсе)

Гм. Если проект небольшой, то разбивать на dll его смысла нет. Если большой, то то всё равно разработчик разобьёт его на логические части, в противном случае его сопровождать и поддерживать будет трудной задачей. Изменение в одной логической части не затронет другие (интерфейс по условию не меняется), соответственно, перекомпилироваться должна бы именно эта логическая часть, а не весь проект. Мне так кажется...


Автор: volatile 11.2.2012, 02:52
feodorv, пересобрать (скажем так), нужно будет весь проект, даже если поменялась одна запятая, во второстепенной строке, самого второстепенного файла.
при изменении Dll ничего пересобирать не нужно, кроме одной этой DLL.

Автор: Dem_max 11.2.2012, 06:53
это все равно что сравнивать жопу с пальцем

Автор: borisbn 11.2.2012, 09:08
Цитата(newbee @  10.2.2012,  21:28 Найти цитируемый пост)
А вот бы было хорошо, если IDE могла держать в памяти рантайм разрабатываемой программы, разработчик написал функцию, скомпилировал одну ее, IDE загрузила ее в рантайм и играйся с ним сколько влезет.

http://msdn.microsoft.com/en-us/library/6wzw9e0y.aspx

Цитата(volatile @  11.2.2012,  01:49 Найти цитируемый пост)
я думаю borisbn, имел ввиду что при изменении участка кода , нужно будет перекомпилировать весь код, который от него зависит.

ага. именно это и имел в виду.

Поясню более конкретно. Есть проект, который делают 3 человека. Вернее сборкой воедино занимается один, а остальные делают для него модули (модуль сетевого взаимодействия, модуль записи в БД и т.п.). Есть два варианта как передавать "сборщику" свои модули - в виде исходников или в виде бинарников. У обоих вариантов есть и плюсы и минусы. Хотелось бы услышать ваше мнение, как бы вы поступали бы.

Цитата(Dem_max @  11.2.2012,  06:53 Найти цитируемый пост)
это все равно что сравнивать

Ооооооч. полезное замечание. Как я раньше без Вашего мнения обходился ?

Автор: bsa 11.2.2012, 09:41
borisbn, при разработке проекта предавать надо исходники.
А чтобы проблем с интерфейсами не было используется PIMPL (см. все нешаблонные классы Qt). В итоге, если ты заменишь интерфейс, но не будешь использовать новые функции, то перекомпиляция dll не потребуется (именно таким образом сохраняется обратная совместимость версий Qt).

Автор: feodorv 11.2.2012, 10:34
Цитата(volatile @  11.2.2012,  02:52 Найти цитируемый пост)
feodorv, пересобрать (скажем так), нужно будет весь проект, даже если поменялась одна запятая, во второстепенной строке, самого второстепенного файла.

Ну, да, пересобирать придётся))))

Всё же ответ не однозначен. При наличии второго (третьего etc) программиста и хорошо определённого, проработанного и оговоренного интерфейса, dll удобнее. Удобнее и в плане разделения ответственности тоже. Я так прикинул, что в моей практике всё, что касалось обмена данных с БД (если это не главная задача программы), выделялось в dll... Иногда соразработчик сам требовал от меня dll. Впрочем, был и случай, когда я сильно пожалел, что разделил программу на модули (хотя по-началу идея казалась здравой)))

Автор: borisbn 11.2.2012, 11:12
Цитата(bsa @  11.2.2012,  09:41 Найти цитируемый пост)
В итоге, если ты заменишь интерфейс, но не будешь использовать новые функции, то перекомпиляция dll не потребуется

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

Цитата(feodorv @  11.2.2012,  10:34 Найти цитируемый пост)
При наличии второго (третьего etc) программиста и хорошо определённого, проработанного и оговоренного интерфейса, dll удобнее

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

Цитата(feodorv @  11.2.2012,  10:34 Найти цитируемый пост)
Я так прикинул, что в моей практике всё, что касалось обмена данных с БД (если это не главная задача программы), выделялось в dll...

Вот точь-в-точь та же фигня smile Что касается других модулей - было по-разному, а вот БД (почему-то) - всегда в dll )))

Добавлено через 2 минуты и 52 секунды
Цитата(bsa @  11.2.2012,  09:41 Найти цитируемый пост)
borisbn, при разработке проекта предавать надо исходники.

тогда более сложный вопрос: как узнать, что стадия разработки закончилась ?
это, скорее, не вопрос к Вам, а так... мысли вслух

Автор: bsa 12.2.2012, 20:47
Цитата(borisbn @  11.2.2012,  12:12 Найти цитируемый пост)
как узнать, что стадия разработки закончилась ?

Стадия разработки заканчивается, когда ты выпускаешь ПО. Дальше в этой версии ты можешь делать только багфиксы и дополнения. Если тебе нужно кардинально что-то изменить, то изволь подготовить другую версию.
Обычно, все часто обновляемые продукты имеют следующий вид версий (может немного меняться): x.y.z, x - версия (серьезные изменения без обратной совместимости), y - подверсия (изменения с обратной совместимостью), z - номер сборки (без изменений интерфейсов вообще - только исправление ошибок). Так вот, когда ты выпустил 1.0.0 - ты закончил разработку версии 1. Но можешь продолжать разработку 2.0.0...

Автор: newbee 12.2.2012, 21:20
Цитата(borisbn @  11.2.2012,  10:08 Найти цитируемый пост)
Ты не поверишь
Это не то. Но уже чуть-чуть теплее.

Автор: k0rvin 15.2.2012, 10:53
Цитата(vol4ek @ 10.2.2012,  20:48)
По мне так динамическая загрузка dll довольно удобная штука.

http://harmful.cat-v.org/software/dynamic-linking/

Автор: borisbn 20.2.2012, 10:25
Ну, и чтобы подытожить выскажу своё мнение: я (в последнее время) за исходники. Мне довольно часто приходилось делать не кроссплатформенные, а кросскомпиляторные dll-ки. Вот список проблем, с которыми приходится сталкиваться:
  •  Нельзя передавать stl-ные классы из одного компилятора в другой (ни указатели на них, ни ссылки), т.к. реализация данных классов может отличаться. Приходится передавать "сырые" указатели и размер
  •  Приходится явно прописывать размер выравнивания для классов и структур (#pragma pack( push, 4 ) / #pragma pack( pop ))? т.к. размер выравнивания, указанный в проекте для dll может отличаться от размера, указанного в проекте для exe
  •  Приходится явно прописывать тип вызова для каждой функции (__stdcall или __cdecl) по той же причине
  •  В дебилдере и в студии отличаются типы вызовов __fastcall, так что такой тип вообще нельзя указывать
  •  В дебилдере и в студии отличаются выравнивание __v_ptr, если указывать выравнивание на 8
  •  В дебилдере и в студии отличается порядок функций в виртуальной таблице, если есть перегруженные функции (при наличии в классе 2-х виртуальных ф-ций foo() и foo( int ) студия меняет их местами в виртуальной таблице)
  •  Нельзя импортировать/экспортировать шаблонные функции (по понятным причинам)
  •  Нельзя выделять память в dll-ке, а освобождать в exe и наоборот, т.к. менеджеры памяти разных компиляторов несовместимы
может и забыл чего-нибудь, но, ИМХО, список и так достаточно большой

Автор: borisbn 19.3.2012, 17:36
ага. забыл.
во всех enum'ах нужно дописывать один элемент, равный 0x7FFFFFFF, потому что в разных проектах по-умолчанию размер enum'ов может быть либо 1 либо 4 байта.
enum Some {
    Some_one,
    Some_two,
    Some_FORCE_DWORD = 0x7FFFFFFF
};

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)