C++ внутреннее повторное использование кода: скомпилировать все или совместно использовать библиотеку / динамическая библиотека?

Одна из самых важных задержек является веб-серверами, получает Ваш запрос к веб-серверу и ответ назад. Эта задержка связывается скоростью света, которой даже должен повиноваться Google. Однако у них есть центры обработки данных во всем мире. В результате среднее расстояние до любого из них ниже. Это подавляет задержку. Несомненно, различие измеряется в миллисекундах, но имеет значение, если ответ должен прибыть в 1 000 миллисекунд.

7
задан sivabudh 11 December 2009 в 22:13
поделиться

4 ответа

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

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

Люди думают, что C определяет ABI. Это не так, и я не знаю ни одного стандартизированного компилируемого языка, который бы это делал. Чтобы ответить на ваш главный вопрос, конечно же, лучше использовать библиотеки - я не могу себе представить, чтобы делать что-то еще.

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

Мы делаем то же самое. Попытка использовать двоичные файлы может быть реальной проблемой, если вам нужно использовать общий код на разных платформах, средах сборки или даже если вам нужны разные параметры сборки, такие как статическая и динамическая привязка к среде выполнения C, различные настройки упаковки структуры и т. Д. .

Я обычно настраиваю проекты так, чтобы собрать как можно больше из исходного кода по запросу, даже с использованием стороннего кода, такого как zlib и libpng. Для тех вещей, которые должны быть созданы отдельно, например, Boost, мне обычно приходится создавать 4 или 8 разных наборов двоичных файлов для различных комбинаций необходимых настроек (отладка / выпуск, VS7.1 / VS9, статический / динамический) и управлять двоичные файлы вместе с файлами отладочной информации в системе управления версиями.

Конечно, если все, кто использует ваш код, используют одни и те же инструменты на одной платформе с одинаковыми параметрами,

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

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

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

Когда мы повторно используем код из старого проекта, мы всегда вводим его как исходный код. Всегда есть что-то, что нужно настроить, и обычно безопаснее настраивать версию для конкретного проекта, чем настраивать общую версию, которая может привести к поломке предыдущего проекта. О возвращении и исправлении предыдущего проекта не может быть и речи, потому что 1) он уже работал (и отправлен), 2) он » s больше не финансируется, и 3) необходимое тестовое оборудование может быть недоступно.

Например, у нас была коммуникационная библиотека, в которой был API для отправки «сообщения», блока данных с идентификатором сообщения, через сокет, канал, что угодно:

void Foo:Send(unsigned messageID, const void* buffer, size_t bufSize);

Но в более позднем проекте нам потребовалась оптимизация: сообщение должно состоять из нескольких блоков данных в разных частях памяти, объединенных вместе, а мы не могли (и не хотели в любом случае) выполнить математические вычисления с указателем, чтобы в первую очередь создать данные в их «собранной» форме, а процесс копирования частей вместе в единый буфер занимал слишком много времени. Поэтому мы добавили новый API:

void Foo:SendMultiple(unsigned messageID, const void** buffer, size_t* bufSize);

, который собирал буферы в сообщение и отправлял его. (Метод базового класса выделил временный буфер, скопировал части вместе и вызвал Foo :: Отправить () ; подклассы могут использовать это как значение по умолчанию или переопределять его своим собственным, например, класс, отправивший сообщение в сокет, просто вызовет send () для каждого буфера, удаляя множество копий.)

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

РЕДАКТИРОВАТЬ: Прочитав комментарий Нила, я подумал о том, что мы делаем, и мне нужно уточнить.

В нашем коде мы делаем много «библиотеки». Много их. В одной большой программе, которую я написал, их было около 50. Потому что для нас и с нашей настройкой сборки это просто.

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

Это работает следующим образом: инструмент находит в каталоге все, что выглядит как исходный файл, генерирует зависимости, если файл изменен, и выдает необходимые правила. Затем он устанавливает правило: взять все и ar / ranlib в файл libxxx.a, названный в честь каталога. Все объекты и библиотеки помещаются в подкаталог, названный в честь целевой платформы (это упрощает поддержку кросс-компиляции). Затем этот процесс повторяется для каждого подкаталога (кроме подкаталогов объектных файлов). Затем каталог верхнего уровня связывается со всеми библиотеками подкаталогов в исполняемый файл, и снова создается символическая ссылка, голая после каталога верхнего уровня.

Итак, каталоги - это библиотеки. Чтобы использовать библиотеку в программе, сделайте на нее символическую ссылку. Безболезненно. Итак, с самого начала все разбито на библиотеки. Если вам нужна общая библиотека, вы добавляете суффикс «.so» к имени каталога.

Чтобы извлечь библиотеку из другого проекта, я просто использую внешнюю Subversion для получения необходимых каталогов. Символические ссылки относительны, так что пока я ничего не оставляю, они все еще работают. При отгрузке мы блокируем внешнюю ссылку для конкретной ревизии родителя.

Если нам нужно добавить функциональность в библиотеку, мы можем сделать одно из нескольких. Мы можем изменить родительский проект (если это все еще активный проект и, следовательно, его можно тестировать), указать Subversion, что нужно использовать более новую ревизию, и исправить любые всплывающие ошибки. Или мы можем просто клонировать код, заменив внешнюю ссылку, если возиться с родителем слишком рискованно. В любом случае, он по-прежнему выглядит для нас «библиотекой», но я не уверен, что он соответствует духу библиотеки.

Мы находимся в процессе перехода на Mercurial, который не имеет механизма «внешних», поэтому мы должны либо клонировать библиотеки в первую очередь, либо использовать rsync для синхронизации кода между различными репозиториями, либо принудительно использовать общую структуру каталогов, чтобы вы могли получать hg pull от нескольких родителей. Последний вариант, похоже, работает неплохо.

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

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

1
ответ дан 6 December 2019 в 23:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: