Сборка исходного кода C ++ в виде библиотеки - с чего начать? - PullRequest
4 голосов
/ 29 мая 2009

За эти месяцы я написал несколько довольно общих функций, которые я хочу создать в виде библиотеки и динамически связывать с ними, а не импортировать 50 с лишним заголовочных / исходных файлов.

Проект поддерживается в Xcode и Dev-C ++ (я понимаю, что мне, возможно, придется идти из командной строки, чтобы делать то, что я хочу) и мне нужно связываться с OpenGL и SDL (динамически в случае SDL). Целевые платформы - Windows и OS X.

Что я вообще смотрю?

  • Какой будет точка входа моего библиотека, если она нужна?
  • Что я должен изменить в своем коде? (Соглашение о вызовах?)
  • Как мне его выпустить? Мое понимание является то, что заголовки и скомпилированные библиотека (.dll, .dylib (, .framework), что бы это ни было) надо быть доступно для проекта - особенно как функциональность шаблона не может быть включен в библиотеку природа.
  • Что еще мне нужно знать?

Ответы [ 3 ]

11 голосов
/ 29 мая 2009

Я бы порекомендовал сборку как библиотеку statc, а не как DLL. Если вы сделаете это, многие проблемы экспорта функций и классов C ++ исчезнут, если вы намереваетесь ссылаться только на код, созданный тем же компилятором, с которым вы создали библиотеку.

Создать статическую библиотеку очень просто, поскольку это просто набор файлов .o / .obj - немного похожий на ZIP-файл, но без сжатия. Вам не нужно ничего экспортировать - просто включите библиотеку в список файлов, с которыми связано ваше приложение. Чтобы получить доступ к определенным функциям или классам, просто включите соответствующий файл заголовка. Обратите внимание, что вы не можете избавиться от заголовочных файлов - от них зависит модель компиляции C ++, особенно для шаблонов.

2 голосов
/ 29 мая 2009

Экспортировать библиотеку классов C ++ из динамической библиотеки может быть проблематично, но это возможно.
Вам нужно пометить каждую функцию для экспорта из DLL (синтаксис зависит от компилятора). Я ковыряюсь в поисках, могу ли я найти, как это сделать из xcode. В VC это __declspec (dllexport), а в CodeWarrior это #pragma export on / # pragma export off.

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

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

Эта статья объясняет проблему именования: http://en.wikipedia.org/wiki/Name_decoration

1 голос
/ 29 мая 2009

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

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

Итак, что вы можете сделать? Я собирал библиотеки C ++ внутри моего исходного кода и следил за тем, чтобы они создавались как часть сборки моего проекта и чтобы все библиотеки и код, ссылающийся на них, использовали одинаковые флаги компилятора.

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

Вы должны быть особенно осторожны с поставляемыми поставщиком динамическими библиотеками C ++ (например, QT в большинстве дистрибутивов Linux). Я видел экземпляры поставляемых поставщиком библиотек, которые были скомпилированы таким образом, что некоторые вещи не могли работать должным образом. Например, некоторые выпуски Redhat Linux (возможно, все они) отключали исключения в QT, что делало невозможным перехват исключений в main (), если исключения были вызваны в обратном вызове QT. Fun.

...