Динамические библиотеки с перекрестной платформой С++; Linux и Windows
Мне нужна помощь в написании кросс-платформенного кода; не приложение, а библиотека.
Я создаю библиотеку как статическую, так и динамическую с большей частью разработки, сделанной в Linux, у меня есть статическая и общая библиотека, сгенерированная в Linux, но теперь я хочу создать версию статической и динамической библиотеки Windows в форме .lib
и .dll
, используя тот же исходный код.
Возможно ли это? Меня немного волнует, потому что я заметил создание файлов Windows .dll
, необходимых с использованием _dllspec
или чего-то подобного в исходном коде.
Если нет, то кто-нибудь может дать мне самое лучшее и быстрое решение для моего кода, скомпилированного в Windows. Мне не нужно делать компиляцию под Linux, я рад сделать это прямо под Windows. Кроме того, я использую две внешние библиотеки, которые являются boost и Xerces XML, которые я установил как для своих окон, так и для Linux-системы, поэтому, надеюсь, они не должны быть проблемой.
Я действительно хочу, чтобы одна копия исходного кода могла быть скомпилирована под Linux и Windows для создания библиотек, специфичных для каждой платформы. Мне все равно, нужно ли мне редактировать код в пользу Windows или Linux, если у меня есть одна копия исходного кода.
Ответы
Ответ 1
В общем, есть две проблемы, которые вам необходимо решить:
- Требование, чтобы в Windows ваша DLL явно экспортировала символы, которые должны быть видимыми для внешнего мира (через
__declspec(dllexport)
и
- Возможность поддерживать систему сборки (в идеале, не нужно поддерживать отдельный файл makefile и проект/решение Microsoft Visual С++).
Во-первых, вам нужно узнать о __declspec(dllexport)
. В проектах только Windows, как правило, это реализовано так, как я описываю в своем ответе на этот вопрос. Вы можете расширить этот шаг дальше, убедившись, что ваш экспортный символ (например, MY_PROJECT_API) определен, но при создании для Linux он ничего не расширяется. Таким образом, вы можете добавить символы экспорта в свой код по мере необходимости для Windows, не затрагивая сборку linux.
Во-вторых, вы можете исследовать какую-то кросс-платформенную систему сборки.
Если вам нравится набор инструментов GNU, вы можете изучить libtool (возможно, в сочетании с automake и autoconf),
Инструменты поддерживаются на Linux и поддерживаются в Windows через Cygwin или MinGW/MSYS. MinGW также дает вам возможность кросс-компиляции, т.е. Создания собственных двоичных файлов Windows во время работы с Linux. Два ресурса, которые я нашел полезными при навигации по Autotools (включая libtool), - это "Autobook" (в частности, раздел DLL и Libtool) и Alexandre Duret-Lutz PowerPoint слайды.
Как уже упоминалось, CMake также является вариантом, но я не могу говорить сам за себя.
Ответ 2
Вы можете довольно легко сделать это с помощью # ifdef's. В Windows _WIN32 должен быть определен компилятором (даже для 64-битного), поэтому код типа
#ifdef _WIN32
# define EXPORTIT __declspec( dllexport )
#else
# define EXPORTIT
#endif
EXPORTIT int somefunction();
должен работать нормально для вас.
Ответ 3
Возможно, это лучше, если вы добавите extern "C"!!!,
/* файл CMakeLists.txt */
SET (LIB_TYPE SHARED)
ADD_LIBRARY(MyLibrary ${LIB_TYPE} MyLibrary.h)
/* файл MyLibrary.h */
#if defined(_WIN32) || defined(__WIN32__)
#if defined(MyLibrary_EXPORTS) // add by CMake
#define MYLIB_EXPORT extern "C" __declspec(dllexport)
#else
#define MYLIB_EXPORT extern "C" __declspec(dllimport)
#endif /* MyLibrary_EXPORTS */
#elif defined(linux) || defined(__linux)
#define MYLIB_EXPORT
#endif
MYLIB_EXPORT inline int Function(int a)
{
return a ;
}