【C言語/C++】DLLエクスポート関係のまとめ

C++

Visual StudioでC言語DLLを作成することがよくあります。DLL作成に関する理解を棚卸したいと思います。

実行環境は下表の通りです。

開発環境Microsoft Visual Studio Community 2019 Version 16.11.7
OSWindows 10 バージョン21H1
実行環境
スポンサーリンク
スポンサーリンク

プロジェクト作成

Visual StudioでC言語、C++のDLLを作る時は、言語をC++とし、『ダイナミック リンク ライブラリ(DLL)』を指定してプロジェクトを作成します。

プロジェクト作成画面

DLL作成

C++での関数エクスポート

作成したプロジェクトには、dllmain.cppとpch.cppの2つしかソースファイルがありませんので、エクスポートする関数用にソースファイルを追加します。名前はsample.cppとします。

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

__declspec (dllexport) void SampleApi1(void)
{
	printf("Hello,Sample1\n");
}

このプロジェクトをビルドすると、『SampleDLL.dll』が出来上がります。関数がエクスポートできているかは、後ほど確認します。

C言語での関数エクスポート

C言語で関数エクスポートする場合は、コーディングの仕方を変えるだけです。

__declspecの前に、『extern “C”』をつけると、対象の関数がC言語関数であることを宣言できます。通常、ソースファイルの拡張子がcppとなっているため、C++とみなされてしまうのです。

ちなみに、sample.cppの拡張子を変更し、sample.cとした場合、下記コードの『extern “C”』は不要となります。

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

extern "C" __declspec (dllexport) void SampleApi1(void)
{
	printf("Hello,Sample1\n");
}

拡張子を『.c』とした場合は、下記のようにします。

#include <stdio.h>

__declspec (dllexport) void SampleApi1(void)
{
	printf("Hello,Sample1\n");
}

エクスポート確認

エクスポート確認は、Visual Studioに同梱されている開発者用コマンド『dumpbin』を使用します。dumpbinは、DLL内のエクスポート関数が確認できます。(他にも多数の機能を搭載しています。)

dumpbin

dumpbinの使い方は、下記の通りです。

【使用方法】
dumpbin /exports DLLファイル名(フルパス、相対パス問わず)

開発者用コマンドプロンプト

dumpbinはVisual StudioツールへのPATHが通っていないと使用できないので、以下のいずれかの方法で開発者用コマンドプロンプトを起動します。

● Visual Studio上で起動する場合は、①ツール(T) → ②コマンドライン(L) → ③開発者コマンドプロンプト(C)をクリック。

Visual Studioから起動

● Windowsメニューから起動する場合、Visual Studio 2019 → Developer Command Prompt for VS 2019をクリック。

Windowsメニューから起動

結果確認

C++で作成したDLLに対してエクスポート確認を行うと、以下の結果となります。赤枠で囲まれた部分にエクスポートされた関数名が表示されているので、本DLLをリンクして関数呼び出しが可能となっています。C++でエクスポートすると、名前修飾(名前マングリング)が発生する点は注意が必要です。

C言語でエクスポートしたDLLに対してエクスポート確認を行うと、以下の結果となります。 C++の場合と同様に、エクスポートされた関数名が確認できます。ただ、名前修飾(名前マングリング)はありません。

まとめ

C言語、C++でのDLL作成についてのポイントは下記の通りです。

  • 作成対象のDLL、エクスポートしたい関数の言語を確認して、コーディングする。
  • 作成する言語は、デフォルトでC++となるので、C言語としてDLLを作成したい場合は、『extern “C”』を書くか、ソースファイルの拡張子を『.c』に変更する。
  • DLL作成後は必ず、dumpbinでエクスポート確認する。

コメント

タイトルとURLをコピーしました