Search code examples
visual-c++mfccomdelete-file

Is there a technical reason why it would be better for the COM DLL to delete the passed in temporary JSON when it is finished with it?


Context

  1. My parent MFC project creates a JSON file:

    CImportFromCLMExplorerDlg::CreateMSATranslationsJson(strTempJson);
    
  2. This temporary file is passed into a C# COM DLL as a parameter for it to use:

    theApp.MSAToolsInterface().ImportHistoryFromCLMExplorer(
                         theApp.GetLanguageCode(dlgImportCLM.GetLanguageToImport()),
                         dlgImportCLM.GetCalendarDBPath(),
                         theApp.GetAssignHistoryXMLPath(),
                         strTempJson);
    
  3. Finally, I delete the temporary file after the above COM DLL method returns:

    ::DeleteFile(strTempJson);
    

My question

It is technically a better approach to get the COM DLL to delete this file once it has finished using it? Or is it perfectly fine (it appears to be) to delete it after in the parent project?

I am not asking for opinions but asking if there is technical reason why it would be better for the COM DLL to delete the passed in temporary JSON when it is finished with it.

The JSON File

The comments allude to the possibility of using an ISteam and not passing a literal file. At the moment I am creating the JSON file like this:

bool CImportFromCLMExplorerDlg::CreateMSATranslationsJson(const CString strPathJson)
{
    CkString strOut, strValue;
    CkJsonObject json;
    bool success;

    LanguageMSA eLang = theApp.GetProgramLanguage();

    // Note: The methods return false if "out of memory"

    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_BIBLE_READING));
    success = json.AddStringAt(-1, "BibleReading", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_BIBLE_READING_MAIN));
    success = json.AddStringAt(-1, "BibleReadingMain", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_BIBLE_READING_AUX));
    success = json.AddStringAt(-1, "BibleReadingAux", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_INITIAL_CALL));
    success = json.AddStringAt(-1, "InitialCall", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_INITIAL_CALL_MAIN));
    success = json.AddStringAt(-1, "InitialCallMain", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_INITIAL_CALL_AUX));
    success = json.AddStringAt(-1, "InitialCallAux", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_RETURN_VISIT));
    success = json.AddStringAt(-1, "ReturnVisit", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_RETURN_MAIN));
    success = json.AddStringAt(-1, "ReturnVisitMain", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_RETURN_AUX));
    success = json.AddStringAt(-1, "ReturnVisitAux", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_BIBLE_STUDY));
    success = json.AddStringAt(-1, "BibleStudy", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_STUDY_MAIN));
    success = json.AddStringAt(-1, "BibleStudyMain", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_STUDY_AUX));
    success = json.AddStringAt(-1, "BibleStudyAux", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_TALK));
    success = json.AddStringAt(-1, "Talk", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_TALK_MAIN));
    success = json.AddStringAt(-1, "TalkMain", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_TALK_AUX));
    success = json.AddStringAt(-1, "TalkAux", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_ASSISTANT));
    success = json.AddStringAt(-1, "Assistant", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_QA));
    success = json.AddStringAt(-1, "QuestionsAndAnswers", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_DISC_VIDEO));
    success = json.AddStringAt(-1, "DiscussionWithVideo", strValue);
    success = json.AddStringAt(-1, "SampleConversation", "Sample Conversation");
    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_INITIAL_CALL_VIDEO));
    success = json.AddStringAt(-1, "InitialCallVideo", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_RETURN_VISIT_VIDEO));
    success = json.AddStringAt(-1, "ReturnVisitVideo", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_VIDEO));
    success = json.AddStringAt(-1, "Video", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_THEME_PRESENTATIONS));
    success = json.AddStringAt(-1, "Presentations", strValue);
    strValue.setStringU(SMMETHOD3(eLang, IDS_STR_THEME_SPIRITUAL_GEMS));
    success = json.AddStringAt(-1, "SpiritualGems", strValue);


    json.put_EmitCompact(false);
    strOut.append(json.emit());
    strOut.append("\r\n");
    
    CkString strPathJsonEx;
    strPathJsonEx.setStringU(strPathJson);
    return strOut.saveToFile(strPathJsonEx, "utf-8");
}

It uses the CkJsonObject and CkString classes. I am not sure if it is possible to turn that into an object that can be passed to the DLL. For the record this is how I read in the JSON in the COM DLL at the moment:

private MSATranslations GetMSATranslations(string strPath)
{
    using (var reader = new StreamReader(strPath, Encoding.UTF8))
        return JsonConvert.DeserializeObject<MSATranslations>(reader.ReadToEnd());
}

Solution

  • Step 1

    Adjust the code that creates the JSON to simply build a `CString`:
    
    bool CImportFromCLMExplorerDlg::CreateMSATranslationsJson(CString &strTranslationsJson)
    {
        CkString strOut, strValue;
        CkJsonObject json;
        bool success;
    
        LanguageMSA eLang = theApp.GetProgramLanguage();
    
        // Note: The methods return false if "out of memory"
    
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_BIBLE_READING));
        success = json.AddStringAt(-1, "BibleReading", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_BIBLE_READING_MAIN));
        success = json.AddStringAt(-1, "BibleReadingMain", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_BIBLE_READING_AUX));
        success = json.AddStringAt(-1, "BibleReadingAux", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_INITIAL_CALL));
        success = json.AddStringAt(-1, "InitialCall", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_INITIAL_CALL_MAIN));
        success = json.AddStringAt(-1, "InitialCallMain", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_INITIAL_CALL_AUX));
        success = json.AddStringAt(-1, "InitialCallAux", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_RETURN_VISIT));
        success = json.AddStringAt(-1, "ReturnVisit", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_RETURN_MAIN));
        success = json.AddStringAt(-1, "ReturnVisitMain", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_RETURN_AUX));
        success = json.AddStringAt(-1, "ReturnVisitAux", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_BIBLE_STUDY));
        success = json.AddStringAt(-1, "BibleStudy", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_STUDY_MAIN));
        success = json.AddStringAt(-1, "BibleStudyMain", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_STUDY_AUX));
        success = json.AddStringAt(-1, "BibleStudyAux", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_TALK));
        success = json.AddStringAt(-1, "Talk", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_TALK_MAIN));
        success = json.AddStringAt(-1, "TalkMain", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_TALK_AUX));
        success = json.AddStringAt(-1, "TalkAux", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_HISTORY_ASSISTANT));
        success = json.AddStringAt(-1, "Assistant", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_QA));
        success = json.AddStringAt(-1, "QuestionsAndAnswers", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_DISC_VIDEO));
        success = json.AddStringAt(-1, "DiscussionWithVideo", strValue);
        success = json.AddStringAt(-1, "SampleConversation", "Sample Conversation");
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_INITIAL_CALL_VIDEO));
        success = json.AddStringAt(-1, "InitialCallVideo", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_RETURN_VISIT_VIDEO));
        success = json.AddStringAt(-1, "ReturnVisitVideo", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_CMB_METHOD_VIDEO));
        success = json.AddStringAt(-1, "Video", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_THEME_PRESENTATIONS));
        success = json.AddStringAt(-1, "Presentations", strValue);
        strValue.setStringU(SMMETHOD3(eLang, IDS_STR_THEME_SPIRITUAL_GEMS));
        success = json.AddStringAt(-1, "SpiritualGems", strValue);
    
        json.put_EmitCompact(false);
        strOut.append(json.emit());
        strOut.append("\r\n");
    
        strTranslationsJson = strOut.getUnicode();
    
        return true;
    }
    

    Step 2

    Pass that string to the API COM wrapper:

    CString strTranslationsJson;
    if (CImportFromCLMExplorerDlg::CreateMSATranslationsJson(strTranslationsJson))
    {
        theApp.MSAToolsInterface().ImportHistoryFromCLMExplorer(
            theApp.GetLanguageCode(dlgImportCLM.GetLanguageToImport()),
            dlgImportCLM.GetCalendarDBPath(),
            theApp.GetAssignHistoryXMLPath(),
            strTranslationsJson);
    }
    

    Step 3

    The wrapper passes it as a CComBSTR to the DLL:

    void CMSATools::ImportHistoryFromCLMExplorer(const CString strLanguageCode, const CString strCalendarDBPath, const CString strHistoryDBPath, const CString strTranslationsJson)
    {
        if (m_pInterface != nullptr)
        {
            CComBSTR bstrLanguageCode(strLanguageCode);
            CComBSTR bstrCalendarDBPath(strCalendarDBPath);
            CComBSTR bstrHistoryDBPath(strHistoryDBPath);
            CComBSTR bstrTranslationsJson(strTranslationsJson);
            m_pInterface->ImportHistoryFromCLMExplorer(bstrLanguageCode,
                bstrCalendarDBPath, bstrHistoryDBPath, bstrTranslationsJson);
        }
    }
    

    Step 4

    Finally, in the DLL we turn that string into our required object:

    private MSATranslations GetMSATranslations(string strTranslationsJson)
    {
        return JsonConvert.DeserializeObject<MSATranslations>(strTranslationsJson);
    }
    

    It works very well. No physical JSON file any more!