Top / Programming / C++Builder / C++ BuilderでDLLの使い方 / C++のオブジェクトをエクスポートするDLL

C++のオブジェクトをエクスポートするDLL

DLLからC++のオブジェクトをエクスポートして、アプリケーション側で使用する方法です。

概要

DLLからC++のオブジェクトをエクスポートには、いくつかの制限があります。

チュートリアル

DLLプロジェクトの作成

  1. C++Builderのメインメニューから「ファイル」-「新規作成」-「その他」を選択します。
  2. 項目カテゴリの「C++Builderプロジェクト」を選択し、「ダイナミックリンクライブラリ」を選択します。
  3. 「OK」ボタンを押します。
  4. 新規ダイナミックライブラリの画面が表示されるので、次のように選択します。

    ソースの種類「C++」
    マルチスレッド「チェックしない」
    VC++スタイルのDLL「チェックしない」

  5. 「OK」ボタンを押します。

以上で、プロジェクトが作成されます。

関数の書き方

エクスポートするクラスを作成します。

//抽象基底クラス
#include <string>
class TPerson
{
public:
  virtual void STDMETHODCALLTYPE SetName(const char* Name) = 0;
  virtual const char* STDMETHODCALLTYPE GetName() const = 0;
};

//派生クラス
class TStudent : public TPerson
{
public:
  TStudent(const char* Name) : FName(Name) {}
  void STDMETHODCALLTYPE SetName(const char* Name) { FName = Name; }
  const char* STDMETHODCALLTYPE GetName() const { return FName.c_str(); }
private:
  std::string FName;
};

オブジェクトの生成と破棄を行う関数を作成します。

extern "C" TPerson* STDMETHODCALLTYPE __declspec(dllexport) CreatePerson()
{
  return new TStudent("Taro");
}
extern "C" void STDMETHODCALLTYPE __declspec(dllexport) DeletePerson(TPerson* Person)
{
  delete Person;
}

全体のソースコードは次のようになります。

#include <windows.h>
#include <string>

//抽象基底クラス
class TPerson
{
public:
  virtual void STDMETHODCALLTYPE SetName(const char* Name) = 0;
  virtual const char* STDMETHODCALLTYPE GetName() const = 0;
};

//派生クラス
class TStudent : public TPerson
{
public:
  TStudent(const char* Name) : FName(Name) {}
  void STDMETHODCALLTYPE SetName(const char* Name) { FName = Name; }
  const char* STDMETHODCALLTYPE GetName() const { return FName.c_str(); }
private:
  std::string FName;
};

//オブジェクトの生成を行う関数
extern "C" TPerson* STDMETHODCALLTYPE __declspec(dllexport) CreatePerson()
{
  return new TStudent("Taro");
}

//オブジェクトの破棄を行う関数
extern "C" void STDMETHODCALLTYPE __declspec(dllexport) DeletePerson(TPerson* Person)
{
  delete Person;
}

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
  return 1;
}

アプリケーションプロジェクトの作成

今回は簡単な動的なロードの方法で作成します。

  1. C++Builderのメインメニューから「ファイル」-「新規作成」-「その他」を選択します。
  2. 項目カテゴリの「C++Builderプロジェクト」を選択し、「コンソールアプリケーション」を選択します。

DLLのオブジェクトの使い方

DLLのオブジェクトの定義を作成します。

class TPerson
{
public:
  virtual void STDMETHODCALLTYPE SetName(const char* Name) = 0;
  virtual const char* STDMETHODCALLTYPE GetName() const = 0;
};

DLLの関数の定義を作成します。

typedef TPerson* (STDMETHODCALLTYPE *TCreatePerson)();
typedef void (STDMETHODCALLTYPE *TDeletePerson)(TPerson* Person);

DLLの読み込みには、LoadLibrary()関数を使用します。

HMODULE hLibModule = LoadLibrary("Project1.dll");

DLLの破棄には、FreeLibrary()関数を使用します。

FreeLibrary(hLibModule);

DLLの関数のアドレスの取得します。

TCreatePerson CreatePerson = reinterpret_cast<TCreatePerson>(GetProcAddress(hLibModule, "CreatePerson"));
TDeletePerson DeletePerson = reinterpret_cast<TDeletePerson>(GetProcAddress(hLibModule, "DeletePerson"));

オブジェクトを作成して、使用します。

TPerson* person = CreatePerson();
std::puts(person->GetName()); //=> Taro
person->SetName("Jiro");
std::puts(person->GetName());//=> Jiro

全体のソースコードは次のようになります。

#pragma hdrstop
#include <tchar.h>
#include <windows.h>
#include <iostream>

class TPerson
{
public:
  virtual void STDMETHODCALLTYPE SetName(const char* Name) = 0;
  virtual const char* STDMETHODCALLTYPE GetName() const = 0;
};

typedef TPerson* (STDMETHODCALLTYPE *TCreatePerson)();
typedef void (STDMETHODCALLTYPE *TDeletePerson)(TPerson* Person);

#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
  HMODULE hLibModule = LoadLibrary("Project1.dll");

  TCreatePerson CreatePerson = reinterpret_cast<TCreatePerson>(GetProcAddress(hLibModule, "CreatePerson"));
  TDeletePerson DeletePerson = reinterpret_cast<TDeletePerson>(GetProcAddress(hLibModule, "DeletePerson"));

  TPerson* person = CreatePerson();
  std::puts(person->GetName()); //=> Taro
  person->SetName("Jiro");
  std::puts(person->GetName()); //=> Jiro

  DeletePerson(person);
  FreeLibrary(hLibModule);

  return 0;
}

おすすめの書籍

更新履歴