Notice : 内容無保証。禁無断転載。リンク自由。

if_03_dll.dll ソース

i_hello.h

#ifndef _i_hello_h_
#define _i_hello_h_

// 提供者が作成し、ユーザに公開する、Chello の interface

// <<interface>>

class Ihello{
public:
    virtual void Delete(void) = 0 ;
    virtual void greet(void) = 0 ;
} ;

//

typedef Ihello* (*PnewHello)(void) ;

#endif /* _i_hello_h_ */

c_hello.h

#ifndef _c_hello_h_
#define _c_hello_h_

// 提供者が作成する、ユーザには非公開の、Chello の specification

#include <i_hello.h>

// <<imprementation>> <<specification>>

class Chello :
    public Ihello
{
public:
    void Delete(void) ;
    void greet(void) ;
} ;

#endif /* _c_hello_h_ */

hello.cpp

// 提供者が作成する、Chello の body と interface の実装

#include <stdio.h>
#include "c_hello.h"

// <<imprementation>> <<body>>

void Chello::Delete(void){
    delete this ;
}

void Chello::greet(void){
    printf("Hello, World!\n") ;
}

// 操作 : 実体
// このDLLからエクスポートしているのは NewHello() だけ

extern "C" __declspec(dllexport) Ihello* NewHello(void){
    return new Chello ;
}

DllMain() -- 略

(VC++ の ウィザードが生成したコードのままなので、DllMain() 等は略。)

if_03.exe ソース

main.cpp

// ユーザが作成する、Chello のメンバを直接使用していないファイル。

#include <i_hello.h>

static Ihello* NewHello(void) ;

int main(void) {
    Ihello* hello = NewHello() ;

    if (hello) {
        hello->greet() ;
        hello->Delete() ;
    }

    return 0 ;
}

// ここから Windows依存部

#include <windows.h>

// # FreeLibrary() のタイミングを考えるのが面倒だったので作ったクラス。
// # 話の本筋とはあまり関係無し。

class CdllMng {
    HINSTANCE   m_hDll ;

public:
    CdllMng(){
        m_hDll = 0 ;
    }

    ~CdllMng(){
        if (m_hDll) {
            FreeLibrary(m_hDll) ;
        }
    }

    FARPROC GetProcAddress(char* dll, char* proc){
        if (!m_hDll) {
            m_hDll = LoadLibrary(__TEXT(dll)) ;
        }

        return m_hDll ? ::GetProcAddress(m_hDll, proc) : 0 ;
    }
} ;

static CdllMng aDll ;

// DLL のロードを実行時に行うことで、
// ユーザはインポートライブラリのリンクを不要にできる。
// つまり、提供者が DLLの実装を変更しても、そのインターフェイスが不変なら
// ユーザの実行形式はそのまま使用できる。
// 逆に、インターフェースさえ同じなら、DLLの実装は複数あっても良く、
// 実行時にユーザが自由に選択することも可能である。

static Ihello* NewHello(void){
    static PnewHello newHello = 0 ;

    if (!newHello) {
        newHello = (PnewHello)aDll.GetProcAddress("if_03_dll.dll", "NewHello") ;
    }

    return newHello ? newHello() : 0 ;
}

戻る
トップページへ戻る