DLLを作成する




オリジナルのDLLを作成して、アクセスする方法を紹介します。
まずは、DLL用のプロジェクトを新規に作成します。
1.プロジェクトの作成
1−1.新規作成−プロジェクトを選択する。
1−2.MFC AppWizard(dll)を選択する。
1−3.プロジェクト名を入力する。
1−4.位置を入力する。
2.STEP1
2−1.作成するDLLの種類:MFCの共有DLLを使用
2−2.オートメーション:チェック無し
2−3.Windowsソケット:チェック有り
2−4.ソースファイルのコメント生成:する
これで、DLLのひな型が自動生成されます。
後は、プロジェクトに関数をどんどん追加していけばOKです。
ただし、注意点が何点かあります。

(サンプル:ZZsocksend_VC.cpp)
//////////////////////////////////////////////////////////////////////////////////
//
// ファイルヘッダ
//
// < プロジェクト名 >       
//
// < プロセス >             共通関数ライブラリ(DLL)
//
// <  ファイル概要  >
// @(s)
//                          ソケット送信処理
//
// < 履  歴 >
// @(h) ZZsocsend_VC.cpp    ver 0.0 ( '99.04.15 )
//      新規作成
//
//////////////////////////////////////////////////////////////////////////////////

// インクルード定義
#include "stdafx.h"
#include "zz_com.h"

#include "nhk_def.h"		// 各端末共通 デファイン定義
#include "nhk_imsg.h"		// 各端末共通メッセージ構造体定義

// デファイン定義


// 外部参照定義
// ソケット切断処理
extern "C" __declspec(dllexport) long __stdcall ZZsocclose_VC(int);

//////////////////////////////////////////////////////////////////////////////////
//
//  関数ヘッダ
//
//  機能     : ソケット送信処理
//
//  返り値   : 正常 RC_NORMAL
//             異常 RC_ERROR
//
//  機能説明 : 電文をソケットに送信する。
//             異常終了時にソケットを削除する。
//
//  備考     : この関数が呼ばれる前に、ソケットの初期化が完了していること。
//             VC++タスクよりコールされる。
//
//
//////////////////////////////////////////////////////////////////////////////////

extern "C" __declspec(dllexport) long __stdcall ZZsocsend_VC(
     int                soc,                // [IN]  ソケットハンドル
     char *             send_buf,           // [IN]  送信バッファ
     unsigned int       send_len            // [IN]  送信サイズ
    )
{
    // 内部参照定義
    long        rsts;                       // 関数戻り値

    rsts = send(soc,send_buf,send_len,0);   // 送信
    if(rsts == SOCKET_ERROR)                // エラー
    {
        rsts = WSAGetLastError( );          // エラー番号取得
        ZZsocclose_VC(soc);                 // ソケット切断
        return RC_ERROR;                    // 異常終了
    }
    return RC_NORMAL;                       // 正常終了
}
必要なヘッダファイルをインクルードします。
ZZsocclose_VC()関数をDLL内の関数から呼び出す時に宣言します。これは、一括してヘッダ ファイルに定義しても構わないと思います。
関数名の宣言はサンプルのように記述します。関数名はZZsocsend_VC()です。


拡張子がdefのファイルに、追加した関数宣言を記述します。
(サンプル:zz_com.def)
; zz_com.def : DLL 用のモジュール パラメータ宣言

LIBRARY      "zz_com"
DESCRIPTION  'zz_com Windows Dynamic Link Library'

EXPORTS
    ; 明示的なエクスポートはここへ記述できます
    ZZsocopen_VC        @1
    ZZsocclose_VC       @2
    ZZsocsend_VC        @3
@の後ろの数字は順番に割り当てて下さい。
後はビルドすればOKです。




DLLが完成したら、それを使用してみましょう。
(サンプル:SVEVdllinit.cpp)
//////////////////////////////////////////////////////////////////////////////////
//
// ファイルヘッダ
//
// < プロジェクト名 >       システム
//
// < プロセス >             サーバイベント管理プロセス
//
// <  ファイル概要  >
// @(s)
//                          DLL初期化処理
//
// < 履  歴 >
// @(h) SVEVdllinit.cpp   ver 0.0 ( '00.06.08 )
//      新規作成
//
//////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SVEVcom.h"

// デファイン定義


// 外部参照定義


//////////////////////////////////////////////////////////////////////////////////
//
//  関数ヘッダ
//
//  機能     : DLL初期化処理
//
//  返り値   : 正常 TRUE
//             異常 FALSE
//
//  機能説明 : DLL化された関数を使用可能にする。
//
//  備考     : 
//
//////////////////////////////////////////////////////////////////////////////////
bool SVEVdllinit( void )
{

    char        DllPathName[255];       // DLLパス
    int         Ret;                    // 関数戻り値


    // デバッグ文出力
    TRACE("%s[%d] 開始\n",__file__,__line__);


    //-----------------------------------------------------------------------------
    /// DLLとのリンクを確立
    //-----------------------------------------------------------------------------

    // DLLファイルパスの取得

                                        // DLLのパス名を取得する
    memset( DllPathName, NULL, sizeof(DllPathName) );
    Ret = SVEVpathget( REGKEY_DLLPATH, DllPathName );
    if( Ret != RC_NORMAL )              // パス名称取得エラーか
    {
        // デバッグ文出力
        TRACE("%s[%d] DLLファイルパス名取得失敗\n",__file__,__line__);

        sprintf( &DllPathName[0], "DLLファイルパス名の取得に失敗しました。\nレジストリキー(%s)を確認してください。", REGKEY_DLLPATH );
                                        // エラー出力メッセージを編集する
        AfxMessageBox( &DllPathName[0], MB_OK | MB_ICONERROR );
                                        // エラーメッセージ表示

        return( FALSE );                // エラーで戻り値を返す
    }

    // パス名とDLL名を連結する
    strcat( DllPathName, DLL_NAME );

    // インスタンスにDLLをリンクする
    Inst_ZZ_VC = LoadLibrary( DllPathName );
    
    // リンク失敗
    if( Inst_ZZ_VC < (HINSTANCE)HINSTANCE_ERROR )
    {
        // デバッグ文出力
        TRACE("%s[%d] LoadLibrary失敗\n",__file__,__line__);

        // エラーでリターンする
        return( FALSE );
    }


    //-----------------------------------------------------------------------------
    /// DLL関数のアドレスを取得
    //-----------------------------------------------------------------------------

    // ソケット送信処理の関数アドレスを取得する
    ZZsocsend_VC = ( long( _stdcall * )( int, char *, UINT ) )
        GetProcAddress( (HMODULE)Inst_ZZ_VC, _T("ZZsocsend_VC" ) );

    // アドレス取得失敗
    if( ZZsocsend_VC == NULL )
    {
        // デバッグ文出力
        TRACE("%s[%d] ZZsocsend_VC()アドレス取得失敗\n",__file__,__line__);

        // エラーでリターンする
        return( FALSE );
    }

    
    // デバッグ文出力
    TRACE("%s[%d] 終了\n",__file__,__line__);

    // 正常でリターンする
    return( TRUE );
}
手順としてはDLLのパス名を取得して、リンクを張ります。
そしてGetProcAddress()関数を用いて関数アドレスに特定のアドレスに関数実体を 割り当てます。


この時、外部変数定義で以下のような定義が必要になります。
//////////////////////////////////////////////////////////////////////////////////////
// DLL参照用宣言
//////////////////////////////////////////////////////////////////////////////////////
// インスタンス
EXTERN  HINSTANCE   Inst_ZZ_VC;         // ZZ_VC.DLLへのインスタンス

//////////////////////////////////////////////////////////////////////////////////////
// DLLの関数プロトタイプ宣言
//////////////////////////////////////////////////////////////////////////////////////
// ソケット送信処理
EXTERN  long ( _stdcall * ZZsocsend_VC )(   int soc, 
                                            char *send_buf,
                                            UINT send_len );




当然DLLを使用し終わったら解放します。
終了関数等に以下の行を追加して下さい。
    //-----------------------------------------------------------------------------
    /// DLLリンク解放処理
    //-----------------------------------------------------------------------------

    // DLLのリンクが有効かチェック
    if( Inst_ZZ_VC >= (HINSTANCE)HINSTANCE_ERROR )
    {
        // DLLのリンクを解放する
        Ret = FreeLibrary( Inst_ZZ_VC );
    }
これで、DLLが使えると思います。




N総研ソフトウェア開発部のTOPに戻る。

このページに関するご意見・質問は
ドンタコスN村 E-mail:se3w-nkmr@asahi-net.or.jp
まで送信してください。