A certain engineer "COMPLEX"

開発メモ その102 CMakeから別ライブラリのクラスを呼び出す

Introduction


会社で自社作成のクラスを提供する話がありましたが、ソースではなく、ライブラリとして提供することになりました。
選択肢は、

  1. 静的ライブラリ
  2. 共有ライブラリ

の2択。
静的にしても良かったのですが、CMakeで共有ライブラリを作って、クラスを呼んだことがないので、共有にしてみました。

サンプルソースは下記になります

Sample source code for Demonstration, Experiment and Test

Answer


基本的に動的ライブラリを作るのは問題ありません。
CMakeLists.txt


add_library(${PROJ_NAME} SHARED ${SOURCES} ${HEADERS})

上記のようにSHAREDをつければ、dllまたはsoファイルが生成されます。
しかし、Windowsの場合、共有ライブラリを使用するには、libファイルが必要になります。
下記のクラスをdllにした場合、どうなるでしょう?


#ifndef _CPP_TEST_H_
#define _CPP_TEST_H_

class Test
{
public:
Test();
virtual ~Test();

int Sum(int a, int b);
};

#endif

生成されたdllをDependency Walkerで見てみました。

何もエクスポートされていません。
そもそも、libファイルがないので、リンクできません。
当然、こんな状態でリンクできません。

共有ライブラリを作って、かつlibファイルを作成するには、一工夫が必要。


#ifndef _CPP_TEST_H_
#define _CPP_TEST_H_

class __declspec( dllexport ) Test
{
public:
Test();
virtual ~Test();

int Sum(int a, int b);
};

#endif

classの後に、dllexport属性を付与します。
シンボルが1つ以上エクスポートされるとlibが生成される模様。

これで、dllと一緒に、libファイルが生成されます。
また、生成されたdllも適切にシンボルをエクスポートできています。

ただし、gccの場合、デフォルトでエクスポートされます。
dllexport属性は余計でビルドエラーを生成しますので、プリプロセッサで切り分けておくと楽です。


#ifdef _WINDOWS
#define CLASSEXPORT __declspec( dllexport )
#else
#define CLASSEXPORT
#endif

#ifndef _CPP_TEST_H_
#define _CPP_TEST_H_

#include "export.h"

class CLASSEXPORT Test
{
public:
Test();
virtual ~Test();

int Sum(int a, int b);
};
#endif

Source Code

https://github.com/takuya-takeuchi/Demo/tree/master/CMake3

コメントを残す

メールアドレスが公開されることはありません。

%d人のブロガーが「いいね」をつけました。