僕がCOMを理解せずに使っているのが根本的な原因であると思います。という前提で、以下のコードを実行します。
IDWriteFactory* pDWriteFactory; IDWriteTextFormat* textFormat; void InitFormat() { // 適当に初期化 pDWriteFactory->CreateTextFormat(,,,, &textFormat); } int Metric(const std::wstring & str) { // 省略記号を生成 IDWriteInlineObject* trimObj = NULL; pDWriteFactory->CreateEllipsisTrimmingSign(textFormat, &trimObj); // オブジェクトを設定する DWRITE_TRIMMING trimming = {DWRITE_TRIMMING_GRANULARITY_CHARACTER, 0, 0}; textFormat->SetTrimming(&trimming, trimObj); // 計算とか ... // 解放 trimObj->Release(); // 幅とか返しとく return 0; }
このうちInitFormatは1回、Metricは複数回実行されています。COMなんだから参照カウンタで自動的にtrimObjの生存期間が管理されている気がしているのですが、タスクマネージャで見ている限りどうも解放されていなさそう。2度目のSetTrimmingって内部でReleaseしないのかなぁ…
さらに、textFormatをReleaseしたタイミングでtrimObjにあたるインスタンスのRelease付近を再帰的に呼び続けてスタックオーバーフローすることも。使い方が間違ってるのかな。。。
trimObj->Release()する前に、SetTrimmingでNULLを指定すると収まったみたい。COMの使い方を完全に間違えてる気しかしない…