您是否缓存LoadLibrary HINSTANCE?

时间:2019-02-18 12:10:32

标签: c++ mfc

这是示例代码:

CString CMeetingScheduleAssistantApp::GetStudyPointDescriptionEx(bool b2019Format, const int iStudyPoint, const bool bFormatText /*false*/)
{
    CString strDescription = _T("<ERROR>");
    LANGUAGE_E eForeignLanguage = GetForeignLanguageGroupLanguageID();

    if (iStudyPoint == 0)
        strDescription = _T("");
    else
    {
        if (UseTranslationINI(eForeignLanguage))
        {
            // Snipped
        }
        else
        {
            HINSTANCE hInst = nullptr;

            if (eForeignLanguage != LANGUAGE_ENGLISH)
                hInst = LoadLibrary(theApp.GetForeignLanguageGroupSatelliteDLLPath());
            else
                hInst = AfxGetInstanceHandle();

            if (b2019Format)
                strDescription.LoadString(hInst, IDS_STR_NEW_STUDY_POINT_01 + (iStudyPoint - 1));
            else
                strDescription.LoadString(hInst,  + (iStudyPoint - 1));

            if (eForeignLanguage != LANGUAGE_ENGLISH)
                FreeLibrary(hInst);
        }

        if (bFormatText) // AJT v16.0.9
        {
            CString strFormattedText;

            strFormattedText.Format(_T("%d - %s"), iStudyPoint, (LPCTSTR)strDescription);
            strDescription = strFormattedText;
        }
    }

    return strDescription;
}

是否注意到该函数调用加载了DLL资源文件?

工作正常。我的问题:

我应该在应用程序类中一次缓存加载该DLL文件,直到用户改变主意,还是应该不断加载和卸载?我需要提取自定义资源值?

1 个答案:

答案 0 :(得分:1)

根据所有评论,请确定缓存。因此,我现在将资源加载到应用程序类的成员变量中。在用户更改设置时,此操作仅执行一次。之后,应用程序使用缓存的实例。

void CMeetingScheduleAssistantApp::LoadForeignLanguageGroupSatelliteFile()
{
    LANGUAGE_E eForeignLanguage = GetForeignLanguageGroupLanguageID();

    ResetForeignLanguageGroupResources();

    // Load the new foreign language resources
    if (UseTranslationINI(eForeignLanguage))
        ReadTranslationINI(m_SatelliteINI, eForeignLanguage, true);
    else
    {
        if (eForeignLanguage == LANGUAGE_ENGLISH)
            m_hInstanceSatelliteDLL = AfxGetInstanceHandle();
        else
            m_hInstanceSatelliteDLL = LoadLibraryEx(GetForeignLanguageGroupSatelliteDLLPath(), nullptr,
                LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE);
    }
}


void CMeetingScheduleAssistantApp::ResetForeignLanguageGroupResources()
{
    if (m_hInstanceSatelliteDLL != nullptr)
    {
        FreeLibrary(m_hInstanceSatelliteDLL);
        m_hInstanceSatelliteDLL = nullptr;
    }
    m_SatelliteINI.clear();
}

由于这是主GUI界面的额外资源集,因此实例存储在自定义变量中,而不是系统变量m_hResource中。

因此,我最初的问题中显示的方法现在看起来像:

CString CMeetingScheduleAssistantApp::GetStudyPointDescriptionEx(bool b2019Format, const int iStudyPoint, const bool bFormatText /*false*/)
{
    CString strDescription = _T("<ERROR>");
    LANGUAGE_E eForeignLanguage = GetForeignLanguageGroupLanguageID();

    if (iStudyPoint == 0)
        strDescription = _T("");
    else
    {
        if (UseTranslationINI(eForeignLanguage))
        {
            CString strLabel, strKey = _T("StudyPoints");

            if (b2019Format)
            {
                strKey = _T("StudyPoints2019");
                strLabel.Format(_T("IDS_STR_NEW_STUDY_POINT_%02d"), iStudyPoint);
            }
            else
                strLabel.Format(_T("IDS_STR_STUDY_POINT_%02d"), iStudyPoint);

            // AJT v17.1.3 We now use our own method
            strDescription = theApp.GetStringFromTranslationINI(m_SatelliteINI, strKey, strLabel);
        }
        else
        {
            if (b2019Format)
                strDescription.LoadString(m_hInstanceSatelliteDLL, IDS_STR_NEW_STUDY_POINT_01 + (iStudyPoint - 1));
            else
                strDescription.LoadString(m_hInstanceSatelliteDLL,  + (iStudyPoint - 1));
        }

        if (bFormatText) // AJT v16.0.9
        {
            CString strFormattedText;

            strFormattedText.Format(_T("%d - %s"), iStudyPoint, (LPCTSTR)strDescription);
            strDescription = strFormattedText;
        }
    }

    return strDescription;
}