SAK 図書館

SAK Streets メインストリート 図書館・カフェ 一覧 SAK Streets 検索
| VB | SQL | Perl | PHP | ASP | JSP | C | PC | HP | FAQ | フリーソフト |

VS.NET C 言語編2 - win32 DLL、__declspec(dllexport)、DllExport、.def

■VC.NET で DLL 作成

  ・むむむっ、昔のお約束とかなり違うぞ。(^^;
    _export FAR PASCAL が恋しい。(^◇^;)

  ・DLL は、関数名に大文字小文字の区別をなくし(内部的に大文字固定)、
    引数スタックを C 標準とは逆の VB や PASCAL 規約の順にするはず。
    WINAPI = FAR PASCAL なので、引数の順序は WINAPI を使用している限り
    問題ない。
    ところが、関数名がどうやっても大文字小文字の区別が付いてしまう。
    .def で大文字固定にすると、今度は VB が区別している...
    私の思い違いなんだろうか... 昔から区別ってあったかな? (^^;

  ・DLL 関数のエクスポートは、_export が古い書式と怒られてしまう。
    __declspec(dllexport) でエクスポートするのが最近のお約束らしい。
    #define DllExport __declspec(dllexport) を使用することにした。

  ・ヘルプでは、なつかしのモジュール定義ファイル(.def) を使用しなくても
    OK と書いてあるのだが、C 言語の内部関数名的にエクスポートされてしま
    う。(_TestFnc@8 とかってやつね。)
    私は、Borland C 派だったもので、.def でエクスポート定義なんかしたこ
    とない。ヘルプ調べまくって書式がわかった。
    「エクスポート名 = オリジナル名」である。
    次の例は、一見同じことに見えるのだが、これを指定すると、
    「TestFnc = _TestFnc@8」と変換される。
    DEF ファイルを作成しなければ、VB では、とっても使いにくい DLL になる。

LIBRARY      Test
EXPORTS
             TestFnc = TestFnc

  ・【追加情報】 「extern "C" __declspec(dllexport)」とすると、
    関数名が C++ ではなく、C の命名規則でエクスポートされ、DEF ファイル
    を不要にできるらしい。
    どうやら、「@」以降の部分は "引数が違うが同名" である関数の衝突を
    避けるためのもので、C++ 以降の仕様とのこと。
    (情報下さった方、ありがとうございます。)

  ・【追加情報2】 win16 のときは #define PASCAL __pascal だったが、
    win32 では #define PASCAL __stdcall となっている。
    __pascal は関数名を全て大文字にするが、__stdcall はそのまま。
    但し、関数名に(C++ かどうかにかかわらず) @8 のようなのが付く。
    (@ の後に数字が並ぶものは __stdcall、そうでないものは C++ の名前修飾
    によるもの)
    今の VB も __stdcall を使っているとのこと。
    (情報下さった方、ありがとうございます。)

■DLL テスト(win32 ダイナミックリンクライブラリ)

  ・VC.NET で、C++ ではなく、C をコンパイルする場合、プリコンパイルヘッダ
    を使用しないようにしないと、コンパイラが正しく動作しない。

/*
========================================================================
  DLL テスト(win32 ダイナミックリンクライブラリ)
========================================================================
*/
// インクルードヘッダ
#include <windows.h>

// 定数宣言
#define DllExport __declspec(dllexport)

// 関数プロトタイプ
DllExport LONG WINAPI TestFnc(LONG a, LONG b);
/*
========================================================================
  メイン
========================================================================
*/
BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
  switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
      break;
  }
  return TRUE;
}
/*
========================================================================
  テスト関数
========================================================================
*/
DllExport LONG WINAPI TestFnc(LONG a, LONG b)
{
  LONG c;

// 加算
  c = a + b;

// リターン
  return c;
}

■パソコン基礎知識 C 言語編資料
■プログラミング言語資料
■パソコン基礎知識 ハード編資料
■パソコン基礎知識 画像編資料
■パソコン基礎知識 Windows 編資料
■コンピュータシステム導入編資料
| VB | SQL | Perl | PHP | ASP | JSP | C | PC | HP | FAQ | フリーソフト |

SAK Streets メインストリート 図書館・カフェ 一覧 SAK Streets 検索



Copyright (C) 1999-2024 Y.SAK