C ++ кроссплатформенные динамические библиотеки; Linux и Windows - PullRequest
26 голосов
/ 05 августа 2009

Мне нужна помощь в написании кроссплатформенного кода; не приложение, а библиотека.

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

Возможно ли это? Я немного обеспокоен, потому что заметил, что генерация файлов Windows .dll требует использования _dllspec или чего-то подобного в вашем исходном коде.

Если нет, то кто-нибудь может посоветовать мне лучшее и самое быстрое решение для компиляции моего кода в Windows. Мне не нужно делать компиляцию под Linux, я счастлив сделать это прямо под Windows. Кроме того, я использую две внешние библиотеки, которые являются boost и Xerces XML, которые я установил в моей системе windows и linux, так что, надеюсь, они не будут проблемой.

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

Ответы [ 3 ]

19 голосов
/ 05 августа 2009

В общем, вам необходимо решить две проблемы:

  1. Требование, чтобы в Windows ваша DLL явно экспортировала символы, которые должны быть видны внешнему миру (через __declspec(dllexport) и
  2. Возможность поддерживать систему сборки (в идеале, не нужно поддерживать отдельный make-файл и Microsoft Visual C ++ Project / Solution)

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

Во-вторых, вы можете исследовать какую-то кроссплатформенную систему сборки.

Если вы знакомы с набором инструментов GNU, возможно, вы захотите изучить libtool (возможно, в сочетании с automake и autoconf). Инструменты изначально поддерживаются в Linux и поддерживаются в Windows через Cygwin или MinGW / MSYS . MinGW также дает вам возможность кросс-компиляции, то есть сборки ваших собственных двоичных файлов Windows во время работы под Linux. Два ресурса, которые я нашел полезными при навигации по Autotools (включая libtool), это "Autobook" (в частности, раздел о DLLs и Libtool ) и PowerPoint Александра Дюре-Лутца слайды .

Как уже упоминали другие, CMake также вариант, но я не могу говорить за него сам.

9 голосов
/ 05 августа 2009

Вы можете довольно легко сделать это с помощью # ifdef. В Windows _WIN32 должен быть определен компилятором (даже для 64-битной), поэтому код вроде

#ifdef _WIN32
#  define EXPORTIT __declspec( dllexport )
#else
#  define EXPORTIT
#endif

EXPORTIT int somefunction();

должно работать нормально.

7 голосов
/ 20 января 2010

Может быть, лучше, если вы добавите 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;
}
...