web-dev-qa-db-ja.com

C ++クロスプラットフォームダイナミックライブラリ; LinuxとWindows

クロスプラットフォームのコードを書くのに助けが必要です。アプリケーションではなく、ライブラリです。

ほとんどの開発がLinuxで行われ、静的と動的の両方のライブラリを作成しています。静的および共有ライブラリをLinuxで生成しましたが、静的および動的ライブラリのWindowsバージョンを_.lib_と_.dll_は同じソースコードを使用します。

これは可能ですか? _.dll_またはソースコードに類似したものを使用して必要なWindows __dllspec_ファイルを生成していることに気付いたので少し心配です。

そうでない場合は、Windowsでコードをコンパイルするための最善かつ最速の解決策を誰かにアドバイスしてもらえますか。 Linuxでコンパイルする必要はありません。Windowsで直接コンパイルできてうれしいです。また、WindowsとLinuxシステムの両方にインストールしたboostとXerces XMLの2つの外部ライブラリを使用しているので、問題がないことを願っています。

私が本当に望んでいるのは、LinuxとWindowsの両方でコンパイルして、各プラットフォームに固有のライブラリを生成できる単一のソースコードコピーを用意することです。単一のソースコードコピーを持つことができる限り、WindowsまたはLinuxを優先してコードを編集する必要があるかどうかは本当に気にしません。

26
iQ.

一般に、注意する必要がある2つの問題があります。

  1. Windowsでは、DLLは、(__declspec(dllexport)を介して)外部に表示されるシンボルを明示的にエクスポートするという要件。
  2. ビルドシステムを維持できる(理想的には、個別のメイクファイルとMicrosoft Visual C++プロジェクト/ソリューションを維持する必要はありません)

まず、__declspec(dllexport)について学ぶ必要があります。 Windowsのみのプロジェクトでは、通常、これは この質問 への回答で説明した方法で実装されます。エクスポートシンボル(MY_PROJECT_APIなど)が定義されていることを確認することで、これをさらに一歩拡張できますが、Linux用にビルドするときに何も展開されません。このようにして、Linuxビルドに影響を与えることなく、Windowsの必要に応じてエクスポートシンボルをコードに追加できます。

2つ目は、ある種のクロスプラットフォームビルドシステムを調査することです。

GNUツールセットに慣れている場合は、 libtool (おそらくautomakeおよびautoconfと組み合わせて)を調査することをお勧めします。ツールはLinuxおよび Cygwin または MinGW/MSYS のいずれかを介してWindowsでサポートされます。MinGWには、クロスコンパイル、つまりLinuxの実行中にネイティブWindowsバイナリを構築するオプションもあります。2つのリソースAutotools(libtoolを含む)をナビゲートするのに役立つことがわかったのは、 "Autobook" (具体的には DLLとLibtool のセクション)と Alexandre Duret-Lutz's PowerPointスライド

他の人が言っているように、 CMake もオプションですが、私自身はそれについて話すことはできません。

19
Nick Meyer

#ifdefを使えばかなり簡単にできます。 Windowsでは、_WIN32はコンパイラによって定義される必要があるため(64ビットの場合でも)、次のようなコードを使用します。

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

EXPORTIT int somefunction();

あなたのためにうまくいくはずです。

10
Rob K

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;
}
7
Cherif