Конечно, есть вещи, отличные от описанных ниже, которые я сейчас не запомнил. Возможно, вы захотите взглянуть на большие кроссплатформенные проекты с открытым исходным кодом, например, на wxWidgets, которые уже рассматривали такие проблемы.
Статический
Статическая библиотека (.a | .lib) похожа на создание zip-файла ваших объектных (.o) файлов, чтобы вы могли управлять ими как одним модулем, когда вы компилируете какую-то другую программу для использования статической библиотеки lib всех объектных файлов он должен быть скомпилирован в.
В большинстве случаев вам не нужно больше ничего делать, вы также можете напрямую включать объектные файлы.
Следует учитывать размер модуля и количество раз, которое вам может понадобиться для использования функций - избегайте статического, если вы хотите использовать библиотеку из более чем одного модуля в одном приложении.
Динамический
Вам нужно будет указать больше, чем ваши стандартные классы для MSVC
- Что экспортировать, используя
__declspec(dllexport)
- Что пользователи библиотеки могут получить, используя
__declspec(dllimport)
- будет ли у вас более одной библиотеки
Пример заглушки заголовка, сделайте его достаточно уникальным, чтобы не конфликтовать с другими библиотеками
// MartinsHeader.h
#ifdef BUILDING_DLL_A
#define DLL_A_EXPIMP __declspec(dllexport)
#else
#define DLL_A_EXPIMP __declspec(dllimport)
#endif
void DLL_A_EXPIMP MyFunction();
class DLL_A_EXPIMP MyClass{};
Классы шаблонов в открытых интерфейсах могут выдавать предупреждения, если они не созданы явно, поэтому весь код шаблона компилируется.
Возможно, вы захотите рассмотреть PIMPL, чтобы минимизировать видимые снаружи изменения в реализации ваших классов. (уменьшите потребность пользователей lib в перекомпиляции для новой lib)
Проблемы с памятью
Время выполнения становится важным с точки зрения того, кто что (де) распределяет.
A) Вы можете придерживаться родной модели памяти, в какой момент
- в некоторых библиотеках будет несколько разных компиляций для однопоточных / многопоточных режимов отладки и выпуска. Это должно соответствовать времени выполнения вызывающего модуля (EXE / DLL)
- Использование классов в интерфейсе часто добавляет требование о том, что вы используете одну и ту же версию класса как в библиотеке, так и в приложении - часто означает несколько компиляций в версии Visual C.
B) Вы можете принудительно (де) выделить память, введя только фабричные выделения и методы уничтожения, чтобы все это выполнялось библиотекой. (Я не большой поклонник этого, поскольку это делает код более сложным, но это может облегчить проблемы во время выполнения)