0
0

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 1 year has passed since last update.

CのdllをCのコンソールアプリケーションから呼び出す際のヘッダファイルの書き方

Posted at

はじめに

この記事のお題はCのdllをCのコンソールアプリケーションから呼び出す際のヘッダファイルの書き方の備忘録です。

この記事内容の作業環境

Windows11 Pro 22H2
CPU Intel(R) Core(TM) i3-5005U 2.00 GHz
Microsoft Visual Studio Community 2022 Version 17.4.4
Microsoft Visual C++ 2022

お題のソースコード

Cのコンソールアプリケーション

consoleApp.c
#include<stdio.h>

#include "dllMain.h"

__declspec(dllimport) void exec();

void main() {
	exec();
}

Cのdll(ダイナミックリンクライブラリ)

dllMain.c
#include<stdio.h>

#define _EXPORTING

#include "dllMain.h"

__declspec(dllexport) void exec(){
	printf("Hello World!\n");
}

Cのdll(ダイナミックリンクライブラリ)のヘッダファイル

dllMain.h
#pragma once

#ifdef _EXPORTING
#define FUNC_DECLSPEC    __declspec(dllexport)
#else
#define FUNC_DECLSPEC    __declspec(dllimport)
#endif

FUNC_DECLSPEC void exec();

当初VS2022のプロジェクトひな形にC++のDLLを指定したので、ヘッダファイルにC++のプリプロセッサディレクティブ#pragma onceが残っています。細かいことは気にしない。

ビルド結果

それではビルドしてみます。ビルド成功のための構成は後でご説明いたします。

 リビルドを開始しました...
1>------ すべてのリビルド開始: プロジェクト:mssqlodbc32, 構成: Debug Win32 ------
1>dllMain.c
1>   ライブラリ C:\developments\dllMain\Debug\dllMain.lib とオブジェクト C:\developments\dllMain\Debug\dllMain.exp を作成中
1>dllMain.vcxproj -> C:\developments\dllMain\Debug\dllMain.dll
2>------ すべてのリビルド開始: プロジェクト:ConsoleApp, 構成: Debug Win32 ------

2>consoleApp.c
2>ConsoleApp.vcxproj -> C:\developments\dllMain\Debug\ConsoleApp.exe
========== すべて再構築: 2 正常終了、0 失敗、0 スキップ ==========
=========== 経過時間 00:07.608 ==========

実行結果

それでは実行してみます。

Hello World!

C:\developments\dllMain\Debug\ConsoleApp.exe (プロセス 15144) は、コード 0 で終了しました。
デバッグが停止したときに自動的にコンソールを閉じるには、[ツール] -> [オプション] -> [デバッグ] -> [デバッグの停止時に自 動的にコンソールを閉じる] を有効にします。
このウィンドウを閉じるには、任意のキーを押してください...

無事にdll経由でHello World!できました。

配置情報

このビルドを成功させるためのソリューション、プロジェクトの配置についてご説明します。
こんな感じです。dllMain.hはConsoleApp側にもコピーして配置しています。

 C:.
│  dllMain.sln
│
├─ConsoleApp
│  │  ConsoleApp.vcxproj
│  │  consoleApp.c
│  │  dllMain.h
│  └─Debug
│
├─Debug
│      ConsoleApp.exe
│      ConsoleApp.pdb
│      dllMain.dll
│      dllMain.exp
│      dllMain.lib
│      dllMain.pdb
│
└─dllMain
    │  dllMain.vcxproj
    │  dllMain.c
    │  dllMain.h
    └─Debug

dll側のCソースには下記の定義があるため

#define _EXPORTING

dll側のヘッダファイルdllMain.hでは

#define FUNC_DECLSPEC    __declspec(dllexport)

が処理され、
コンソールアプリ側のCソースにはこの定義がないため
コンソールアプリ側のヘッダファイルdllMain.hでは

#define FUNC_DECLSPEC    __declspec(dllimport)

が処理され、

FUNC_DECLSPEC void exec();

は、それぞれの意味となって、双方で共通のヘッダファイルとしてインクルードできるようになります。

よくあるビルドエラー

C:\developments\dllMain\Debug\dllMain.libのパスをコンソールアプリ側のプロジェクトのプロパティの
リンカー->入力->追加の依存ファイル
に設定し忘れているとConsoleApp側のビルドが下記のように失敗します。

2>consoleApp.c
2>consoleApp.obj : error LNK2019: 未解決の外部シンボル __imp__exec が関数 _main で参照されました
2>C:\developments\dllMain\Debug\ConsoleApp.exe : fatal error LNK1120: 1 件の未解決の外部参照
2>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(1096,5): error MSB6006: "link.exe" はコード 1120 を伴って終了しました。
2>プロジェクト "ConsoleApp.vcxproj" のビルドが終了しました -- 失敗。

おわりに

C言語でのdll作成の情報は少ないので何かの参考になれば幸いです。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?