Introduction

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

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

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

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

Answer

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
#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ファイルを作成するには、一工夫が必要。

1
2
3
4
5
6
7
8
9
10
11
12
13
#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属性は余計でビルドエラーを生成しますので、プリプロセッサで切り分けておくと楽です。

1
2
3
4
5
#ifdef _WINDOWS
#define CLASSEXPORT __declspec( dllexport )
#else
#define CLASSEXPORT
#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#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/CMake/03_CMake3