Почему PrivateFontCollection AddFontFile выбрасывает исключение нарушения прав доступа? - PullRequest
1 голос
/ 04 июля 2019

Попытка добавить собственный шрифт в приложение C ++ MFC, используя следующий код:

void CMFCApplication1View::OnInitialUpdate()
{
    CFormView::OnInitialUpdate();

    // ...

    // dynamic path 
    std::string test = std::string("Oswald.ttf");
    std::string path = this->ExePath() + test;
    std::wstring widestr = std::wstring(path.begin(), path.end());
    const wchar_t* widecstr = widestr.c_str();

    // hardcoded path
    std::string s = R"(D:\DEV\C\CTests\MFCApplication1\Debug\Oswald.ttf)";
    std::wstring r = std::wstring(s.begin(), s.end());
    const wchar_t* t = r.c_str();

    Gdiplus::PrivateFontCollection m_fontcollection;
    Gdiplus::Status nResults = m_fontcollection.AddFontFile(t); // access violation exception thrown here

    // ...
}

std::string CMFCApplication1View::ExePath() {
    char buffer[MAX_PATH];
    GetModuleFileNameA(NULL, buffer, MAX_PATH);
    std::string::size_type pos = std::string(buffer).find_last_of("\\/");
    return std::string(buffer).substr(0, pos + 1);
}

Я новичок в C ++ (из C #).Код вызывает исключение нарушения прав доступа при вызове AddFontFile, как с жестко закодированной, так и с динамической версией, но значение пути является правильным.

Я что-то упускаю из виду?


Обновление

Это то, что я сделал сейчас, основываясь на комментариях.Кажется, что это работает, и больше нет ничего конверсионного, но, как я уже сказал, потребуется некоторое время, пока я не буду уверен, что все делаю правильно.

void CMFCApplication1View::OnInitialUpdate()
{
    CFormView::OnInitialUpdate();

    // ...

    // font path 
    // const wchar_t* path = (this->ExePath() + std::wstring(L"Oswald.ttf")).c_str();
    const wchar_t* path = &(this->ExePath() + std::wstring(L"Oswald.ttf"))[0];

    // Gdiplus init
    ULONG_PTR gdiplusToken; 
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    // Gdiplus font
    Gdiplus::PrivateFontCollection m_fontcollection;
    Gdiplus::Status nResults = m_fontcollection.AddFontFile(path);

    // ...
}

std::wstring CMFCApplication1View::ExePath() {
    wchar_t buffer[MAX_PATH];
    GetModuleFileNameW(NULL, buffer, MAX_PATH);
    std::wstring::size_type pos = (std::wstring(buffer)).find_last_of(L"\\/");
    return std::wstring(buffer).substr(0, pos + 1);
}

Преобразования выше с использованием c_str () илиназначение & wstring [0] основано на этом ответе: https://stackoverflow.com/a/16113660/2983568

...