11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

dllexportとdllimportの使い方

Last updated at Posted at 2020-08-30

#DLLで関数を共有する方法
Windowsでライブラリ(DLL)を作る時、以下の方法で関数を他のDLLやEXEに共有できます。
①DEFファイルで共有
②DEFファイル無しで共有

上記の①は、関数名をDEFファイルに記載することで共有する方法になりますが、本記事は上記の②をメモします。

#ファイル構成
image.png

①DLLをコンパイル
②EXEがDLLのヘッダーファイルとLIBファイルを参照
③EXEのソースファイル、参照されているDLLのヘッダーファイルとLIBファイルを用いてEXEをコンパイル
④EXEの実行時にDLLが参照される

#関数のエクスポートとインポート
##他のDLLやEXEに関数をエクスポート

a.h
// 関数の宣言
void __declspec(dllexport) hello();
a.c
//関数の定義
void hello(){
   printf("hello\n");
}

「__declspec(dllexport)」を使って、「この関数を外部に公開するよ」という宣言で共有したい関数を公開できます。
これに対して、この共有関数を使いたい他のDLLやEXEで、「dllexport」ではなく「dllimport」を使えば、
「この関数は、外部から取るよ」のように関数を宣言できます。
以下は例です:

b.c
void __declspec(dllimport) hello();   // 外部関数の宣言(リンカーでa.libを指定する必要がある)

int main(){
   hello();   // 外部関数の実行
   return 0;
}

##もう少し工夫する
上記のように、EXEのCファイルに直接外部関数の宣言を書いても実行できますが、
参照のDLLにある関数が変更するたびに、EXEのCファイルも合わせて変更しないといけません。

このため、DLLのヘッダーファイルを直接に参照できれば便利になります。

しかし、DLLのヘッダーファイルをそのまま参照しますと、EXE側も「dllexport」になりますので、
下記のように、もう少し工夫する必要はあります。

a.h
#ifdef A_EXPORTS
#define DECLSPEC __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport)
#endif

DLLのヘッダーファイルをこのように修正すれば、DLLのプロジェクトで「A_EXPORTS」という
マクロをプリプロセッサで定義するだけで、DLLでは「A_EXPORTS」が定義されいるため
エクスポートになって、EXEでは「A_EXPORTS」が定義されていないためインポートになります。

これで、上記のファイル構成図のような構成で、DLLの関数の関数名や引数の型・数が
変更されない限り、DLL側で関数の処理の中身を変更しても、EXE側で何もしなくてもよいです。

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?