全体構成
cimgui/ ← クローン済み
cimgui.cpp
cimgui.h
cimgui_impl.cpp ← DX11バックエンドのCラッパー
cimgui_impl.h
imgui/ ← サブモジュール
imgui.cpp
imgui_draw.cpp
imgui_tables.cpp
imgui_widgets.cpp
backends/
imgui_impl_dx11.cpp
imgui_impl_win32.cpp
↓ MSVCでDLLビルド
cimgui.dll ← TCCからリンクするDLL
cimgui.def ← tiny_impdefで生成
↓ TCCでコンパイル
my_app.c → my_app.exe
Step 1: サブモジュールの初期化
クローン後にサブモジュール(imgui本体)を取得する。
cd cimgui
git submodule update --init --recursive
完了後、imgui/ フォルダ内に imgui.cpp, backends/imgui_impl_dx11.cpp などが入っていることを確認。
Step 2: cimgui.dll を MSVC でビルド
2-1. Developer Command Prompt を開く
「x64 Native Tools Command Prompt for VS 2022」を使用。
2-2. backends_wrapper.cpp を作成
cimgui/ 直下に以下の内容でファイルを作成する。IMGUI_IMPL_API を空にすることで二重装飾を防ぎ、cimgui_impl.cpp 側のラッパーから正しく呼び出せるようにする。
// backends_wrapper.cpp
#define IMGUI_IMPL_API
#include "imgui/backends/imgui_impl_dx11.cpp"
#include "imgui/backends/imgui_impl_win32.cpp"
2-3. ビルドコマンド
cimgui/ フォルダをカレントにして実行:
cl.exe /LD /O2 /MD /EHsc ^
/DCIMGUI_DLL ^
/I. /Iimgui /Iimgui/backends ^
cimgui.cpp ^
cimgui_impl.cpp ^
imgui/imgui.cpp ^
imgui/imgui_draw.cpp ^
imgui/imgui_tables.cpp ^
imgui/imgui_widgets.cpp ^
imgui/imgui_demo.cpp ^
backends_wrapper.cpp ^
/link d3d11.lib dxgi.lib user32.lib ^
/OUT:cimgui.dll
ビルドオプションの説明
| オプション | 意味 |
|---|---|
/LD | DLLとしてビルド |
/DCIMGUI_DLL | エクスポートマクロを有効化 |
/MD | マルチスレッドDLL CRT(Releaseビルド) |
imgui_demo.cpp | ShowDemoWindow など必須関数を含む(忘れるとリンクエラー) |
backends_wrapper.cpp | バックエンドを IMGUI_IMPL_API 空で取り込むラッパー |
2-4. 生成物の確認
cimgui.dll ← メイン
cimgui.lib ← インポートライブラリ(TCCでは使わない)
cimgui.exp
Step 3: .def ファイルの生成
tiny_impdef を使って cimgui.dll から .def を生成する。
tiny_impdef cimgui.dll -o cimgui.def
tiny_impdef の場所: TCCのインストールフォルダ(例:
C:\tcc\tiny_impdef.exe)
生成された cimgui.def の冒頭がこのような形式であることを確認:
LIBRARY cimgui.dll
EXPORTS
igBegin
igEnd
igNewFrame
igRender
ImGui_ImplDX11_Init
ImGui_ImplDX11_NewFrame
ImGui_ImplDX11_RenderDrawData
ImGui_ImplWin32_Init
ImGui_ImplWin32_NewFrame
...
Step 4: TCC 用の C コードを書く
4-1. 必要なヘッダの扱い
cimgui.h と cimgui_impl.h はそのままインクルードできる。ただし以下のマクロ定義をインクルードの前に必ず入れる。
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
#include "cimgui.h"
#include "cimgui_impl.h"
4-2. 初期化コード
既存の tcc_dx11_mina.c の InitD3D() 成功後に追加:
// Win32バックエンド初期化
ImGui_ImplWin32_Init(hwnd);
// DX11バックエンド初期化(g_dev, g_ctx は既存のDX11デバイス)
ImGui_ImplDX11_Init(g_dev, g_ctx);
// ImGuiコンテキスト作成
igCreateContext(NULL);
// スタイル設定(任意)
igStyleColorsDark(NULL);
4-3. Render() に ImGui 描画を追加
void Render()
{
float clearColor[4] = { 0.0f, 0.2f, 0.4f, 1.0f };
g_ctx->lpVtbl->ClearRenderTargetView(g_ctx, (void*)g_backbuffer, clearColor);
g_ctx->lpVtbl->OMSetRenderTargets(g_ctx, 1, (void* const*)&g_backbuffer, NULL);
// --- ImGui フレーム開始 ---
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
igNewFrame();
// --- UI 描画 ---
int show = 1;
igShowDemoWindow(&show); // デモウィンドウ
// 独自ウィンドウ例
igBegin("Hello from TCC!", NULL, 0);
igText("DirectX11 + cimgui + TCC");
if (igButton("Click me", (ImVec2){0,0})) {
// ボタン押下時の処理
}
igEnd();
// --- ImGui 描画実行 ---
igRender();
ImGui_ImplDX11_RenderDrawData(igGetDrawData());
g_swapchain->lpVtbl->Present(g_swapchain, 1, 0);
}
4-4. WndProc に Win32メッセージ処理を追加
// WndProc の先頭に追加
extern int ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// ImGuiがメッセージを処理した場合は早期リターン
if (ImGui_ImplWin32_WndProcHandler(hwnd, msg, wParam, lParam))
return TRUE;
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
4-5. クリーンアップ
void Cleanup()
{
ImGui_ImplDX11_Shutdown();
ImGui_ImplWin32_Shutdown();
igDestroyContext(NULL);
CleanupD3D(); // 既存のDX11クリーンアップ
}
Step 5: TCC でコンパイル
my_app.c, cimgui.dll, cimgui.def, d3d11.def を同じフォルダに置いて:
tcc my_app.c cimgui.def d3d11.def -o my_app.exe
実行時の配置
my_app.exe
cimgui.dll ← 必須(同じフォルダ)
d3d11.dll ← Windows標準、システムにある
D3DCompiler_47.dll ← シェーダーコンパイルに必要
よくあるビルドエラーと対処
imgui_impl_win32.cpp が WndProcHandler をエクスポートしていない
cimgui_impl.cpp を確認し、imgui_impl_win32 の関数が含まれているか確認。 なければ imgui/backends/imgui_impl_win32.cpp を明示的にビルドに追加。
TCC で ImVec2 がエラーになる
cimgui.h の前に必ず #define CIMGUI_DEFINE_ENUMS_AND_STRUCTS を定義する。
DLL が見つからない(実行時エラー)
cimgui.dll を my_app.exe と同じフォルダに置く。 または環境変数 PATH に追加。
igGetDrawData() の戻り値が NULL
igNewFrame() と igRender() の間に必ず何かUIを描画すること(igShowDemoWindow だけでもOK)。
ファイル構成まとめ(ビルド後)
project/
my_app.c ← TCC でコンパイルするメインコード
cimgui.h ← cimguiのヘッダ(インクルード用)
cimgui_impl.h ← バックエンドのヘッダ(インクルード用)
cimgui.dll ← MSVCでビルドしたDLL
cimgui.def ← tiny_impdefで生成
d3d11.def ← 添付のもの(既存)
my_app.exe ← TCC出力