2012年12月25日火曜日

ダイナミックライブラリのエントリポイント

ダイナミックライブラリのエントリポイントはWindows環境ならDllMainで良いけどLinux環境でどのように実現すればよいのか困っていたけどグローバル変数とコンストラクタとデストラクタを使うと似たような振る舞いを実現できます。以下はその例です。

共通ライブラリがロードされるとグローバル変数がインスタンス化されて、DLManagerのコンストラクタが呼び出されます。グローバル変数のインスタンス化はエントリポイントの開始よりも先に呼び出されるので、初期化の位置としては悪くないように思います。
アンロードの場合もエントリポイントを抜けたあとにデストラクタが呼び出されます。

共通ライブラリのロードアンロードクラス
///
/// DLManager.cpp
///
#include <iostream>

class DLManager
{
public:
 DLManager()
 {
  std::cout << "Test library start!!" << std::endl;
 }

 ~DLManager()
 {
  std::cout << "Test library end!!" << std::endl;
 }
};

///
/// グローバル空間にインスタンス化する
///
static DLManager _dlManager;

DLL内に定義されている例題クラス
///
/// Someone.h
///
#ifndef _INC_HEADER_H_
#define _INC_HEADER_H_

#ifdef _TEST
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif

class TEST_API Someone
{
public:
 Someone();
 ~Someone();
 void Do();
};

#endif

///
/// Someone.cpp
///
#include <iostream>
#include "Someone.h"

Someone::Someone()
{
}

Someone::~Someone()
{
}

void Someone::Do()
{
 std::cout << "something" << std::endl;
}

エントリポイント
///
/// Main.cpp
///
#include <iostream>
#include "Someone.h"

int _tmain(int argc, _TCHAR* argv[])
{
 Someone one;
 one.Do();
 return 0;
}

出力結果
Test library start!!
something
Test library end!!

0 件のコメント:

コメントを投稿