Пользование совместно использованными библиотеками по сравнению с единственным исполняемым файлом

Да, это - 32 бита

7
задан jackhab 28 November 2015 в 17:29
поделиться

9 ответов

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

Но зачем вам оборачивать классы C ++ в интерфейсы C-функций, кроме, может быть, для создания объекта?

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

8
ответ дан 6 December 2019 в 07:07
поделиться

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

РЕДАКТИРОВАТЬ: Я действительно не вижу причин, по которым вам нужно оборачивать классы C ++ с использованием интерфейсов C - это делается за кулисами. В Linux вы можете использовать разделяемые библиотеки без какой-либо специальной обработки. Однако в Windows вам потребуется ___ declspec (экспорт) и ___ declspec (импорт).

5
ответ дан 6 December 2019 в 07:07
поделиться

Улучшить повторное использование, даже если его не будет? Это не звучит как веский аргумент.

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

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

4
ответ дан 6 December 2019 в 07:07
поделиться

Краткий ответ: нет.

Более длинный ответ: динамические библиотеки ничего не добавляют к тестированию, модульности или повторному использованию, что не может быть сделано так же легко в монолитном приложении. Единственное преимущество, о котором я могу думать, это то, что это может заставить создать API в команде, у которой нет дисциплины, чтобы делать это самостоятельно.

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

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

2
ответ дан 6 December 2019 в 07:07
поделиться

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

Если у вас сейчас нет проблем с тестированием, я бы рекомендовал оставить ваше приложение как есть. Модульность - это замечательно, но в Linux есть своя собственная версия "DLL hell" (см. ldconfig ), и вы уже указали, что повторное использование не является необходимостью.

1
ответ дан 6 December 2019 в 07:07
поделиться

Ваша ошибка связана с тем, что у вас:

     JOIN user ON article.author_id = user.id
LEFT JOIN user ON article.modified_by = user.id

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

     JOIN USER u ON article.author_id = u.id
LEFT JOIN USER u2 ON article.modified_by = u2.id

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

Следующие проблемы, которые необходимо решить, будут:

SELECT article.* , section.title, category.title, user.name, user.name

1) Никогда не используйте SELECT * - всегда указывайте нужные столбцы, даже если это вся таблица. Прочтите этот вопрос SO, чтобы понять, почему .

2) Вы получите неоднозначные ошибки столбца, связанные со столбцами user.name , потому что, опять же, база данных не может определить, какая таблица экземпляр, из которого нужно извлечь данные. Использование псевдонимов таблиц устраняет проблему:

Повторное использование кода?

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

Заключение

Пункты 1 и 2 все еще могут быть достигнуты с помощью статического библиотеки. Число 3 сделает разделяемые библиотеки обязательными.

Теперь, если у вас есть более одной глубины связывания библиотек (я думаю о соединении вместе двух статических библиотек, которые уже были скомпилированы для связывания других библиотек), это может быть сложно. В Windows это приводит к ошибке связывания, поскольку на некоторые функции (обычно функции времени выполнения C / C ++ при статической связи) ссылаются более одного раза, и компилятор не может выбрать, какую функцию вызвать. Я не знаю, как это работает в Linux, но думаю, что это тоже может случиться.

Анализ ваших собственных аргументов

Ваши собственные аргументы несколько необъективны:

Бремя компиляции / связывания разделяемых библиотек?

Бремя компиляции и связывания совместно используемых библиотек по сравнению с компиляцией и линковкой к статическим библиотекам не существует. Итак, этот аргумент не имеет значения.

Динамическая загрузка / выгрузка?

Динамическая загрузка / выгрузка разделяемой библиотеки может быть проблемой в очень ограниченном варианте использования. В обычных случаях ОС загружает / выгружает библиотеку, когда это необходимо, без вашего вмешательства, и в любом случае ваши проблемы с производительностью кроются в другом месте.

Отображение кода C ++ с интерфейсами C?

Что касается использования интерфейса C-функции для вас C ++ кода, я не понимаю: вы уже связываете статические библиотеки с интерфейсом C ++. Связывание разделяемых библиотек ничем не отличается.

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

Бинарный файл с одним файлом проще?

Вы правы.

В Windows разница незначительна, но все же существует проблема с DLL Ад , который исчезает, если вы добавляете версию в имена библиотек или работаете с Windows XP.

В Linux, помимо проблемы с Windows, описанной выше, у вас есть тот факт, что по умолчанию общие библиотеки должны быть в некоторых системных каталогах по умолчанию, чтобы их можно было использовать, поэтому вам придется скопировать их туда при установке (что может быть проблемой ...) или изменить некоторые настройки среды по умолчанию (что тоже может быть проблемой ...)

Заключение: Кто прав?

Теперь ваша проблема не в том, «прав ли мой коллега?». Он. Как и вы.

Ваша проблема:

2
ответ дан 6 December 2019 в 07:07
поделиться

Если вы задаете вопрос, а ответ не очевиден, оставайтесь на месте. Если вы еще не дошли до того момента, когда создание монолитного приложения занимает слишком много времени или для вашей группы слишком сложно работать вместе, тогда нет веских причин для перехода к библиотекам. Вы можете создать тестовую среду, которая работает с файлами приложения, если хотите, как она есть, или вы можете просто создать другой проект, который использует те же файлы, но присоединить тестовый API и построить с ним библиотеку.

Для целей доставки , если вы хотите создавать библиотеки и поставлять один большой исполняемый файл, вы всегда можете связать их статически.

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

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

1
ответ дан 6 December 2019 в 07:07
поделиться

Общие библиотеки имеют свою головную боль, но я думаю, что общие библиотеки - это правильный путь. Я бы сказал, что в большинстве случаев вы должны иметь возможность делать части своего приложения модульными и многократно использовать в других местах вашего бизнеса. Кроме того, в зависимости от размера этого монолитного исполняемого файла, может быть проще просто загрузить набор обновленных библиотек вместо одного большого файла.

ИМО, библиотеки в целом приводят к лучшему коду, более тестируемому коду и позволяют использовать его в будущем. проекты, которые нужно создавать более эффективно, потому что вы не изобретаете велосипед заново.

Короче говоря, я согласен с вашим коллегой.

1
ответ дан 6 December 2019 в 07:07
поделиться

В Linux (и Windows) вы можете создать общую библиотеку с помощью C ++ и не загружать ее с помощью экспорта функций C.

То есть вы встраиваете classA.cpp в classA.so , и вы создаете classB.cpp в classB (.exe), который ссылается на classA.so. Все, что вы на самом деле делаете, - это разбиваете приложение на несколько двоичных файлов. Это имеет то преимущество, что они быстрее компилируются, проще в управлении, и вы можете писать приложения, которые загружают только этот код библиотеки для тестирования.

Все по-прежнему C ++, все ссылки, но ваш .so отделен от вашего статически связанного application.

Теперь, если вы хотите загрузить другой объект во время выполнения (т. е. вы не знаете, какой из них загружать до выполнения), вам нужно будет создать общий объект с помощью c-exports, но вы будете также загружать эти функции вручную;

1
ответ дан 6 December 2019 в 07:07
поделиться