tmytのらくがき

個人の日記レベルです

DirectWriteではまり続けてた

僕が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の使い方を完全に間違えてる気しかしない…