既存のC++/CLIプロジェクトを調査するために、Doxygenで呼び出し関係図を出力させました。
しかしソースとにらめっこしてみると、何故か出力されない関数があることが明らかになりました……
ということで、原因を調査してみました。
結論
C++の場合、クラス定義内だとヘッダファイルにも、定義でなくロジックが書けてしまいます。
どうやらコレが問題でした。
普通はやらないと思いますが、改めて……
ヘッダにロジックを書くのはやめよう!
調査用プロジェクトの作成
調査用に新規プロジェクトを作成しました。
Visual C++ > CLR > Windows フォームアプリケーション
ソースコード
調べるのに使用したソースコードです。
Form1_Load()を起点に、色んな所の関数をアクセスしている感じです。
Form1.h
追加したコード近辺以外の自動生成コードは省略しています。
適当にテキストボックス(text)を作成し、文字列を追加していく処理を作成しました。
#pragma once #include "stdafx.h" #include "sub.h" #include "hoge.h" #include <stdio.h> #include <iostream> #include <msclr/marshal_cppstd.h> using namespace std; namespace TestDoxygen { (中略) String^ sS(string s) { return msclr::interop::marshal_as<System::String^>(s); } void FuncA() { text->Text += "FuncA\r\n"; } void FuncB() { text->Text += "FuncB\r\n"; FuncC(); } void FuncC() { text->Text += "FuncC\r\n"; } void FuncD() { text->Text += "FuncD\r\n"; string child = FuncX(); text->Text += sS(child); } private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) { FuncA(); FuncB(); // -> call FuncC FuncD(); FuncY(); hoge^ h = gcnew hoge(); text->Text += sS(h->hogeA()); text->Text += sS(h->hogeD()); } }; }
sub.cpp/h
sub.h
#pragma once #include "stdafx.h" #include <iostream> extern std::string FuncX(); extern std::string FuncY();
sub.cpp
#include "stdafx.h" #include "sub.h" std::string FuncX() { std::string name = "FuncX\r\n"; name += "- "; name += FuncY(); return name; } std::string FuncY() { std::string name = "FuncY\r\n"; return name; }
hogeクラス
hoge.cpp
#pragma once #include <iostream> using namespace std; ref class hoge { public: hoge(void); string hogeA() { string name = "hogeA\r\n"; name += hogeB(); name += hogeC(); return name; } string hogeB() { string name = "hogeB\r\n"; name += hogeC(); return name; } string hogeC(); string hogeD(); string hogeE(); };
hoge.cpp
#include "StdAfx.h" #include "hoge.h" hoge::hoge(void){} string hoge::hogeC() { return "hogeC\r\n"; } string hoge::hogeD() { string name = "hogeD\r\n"; name += hogeE(); return name; } string hoge::hogeE() { return "hogeE\r\n"; }
結果
なにかをコールしている関数について挙げていきます。
このような結果になりました。
Form1_Load(Form1.h)
FuncB(Form1.h)
呼び出し関係図なし
FuncD(Form1.h)
FuncX(sub.cpp)
hogeA(hoge.h)
呼び出し関係図なし
hogeB(hoge.h)
呼び出し関係図なし
hogeD(hoge.cpp)
謝辞
teratailでご回答くださった方々、ご覧頂いた方々、ありがとうございました。
あとがき
C++/CLI→Doxygenの呼び出し関係図に出力されない関数を調査した結果でした!
なぜForm1.hにゴリゴリ処理を描いてしまったのか……
うらめしい限りです……
とはいえ原因は判明したので、これでやっと対処ができます……