I originally asked this question due to difficulties I had getting to the bottom of my problem. but as i have now completely re written the code I was using from the documentation but still get the same issue I felt it better to completely re-word the question now that I think I have a handle on what the problem is.
I am trying to write Plugins (dll's) to extend the functionality of some existing software (Mach3)
This software uses XML files to store settings for each profile, and on closing this file may be accessed by multiple threads concurrently, but the main thread is the last to save and close the object. I believe that this is what CoCreateInstance is intended for by creating only a single instance that can have multiple references open simultaneously for threads to work with/on.
Originally I was using visual studio 2003 inside a virtual machine, but I am now using visual studio 2013.
when using vs2003 I found no problems saving additional settings, however when compiled using vs2013 it seems to fail, yet no error codes or messages are flagged.
the code I'm using now is:
// XMLProfile.cpp #include "stdafx.h" #include "XMLProfile.h" // CXMLProfile extern CString ProfileName; CXMLProfile::CXMLProfile() { CoInitialize(NULL); hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&m_XMLDoc); Debug(hr); VARIANT_BOOL vResult; hr = m_XMLDoc->load(COleVariant(ProfileName), &vResult); Debug(hr); if (((bool)vResult) == TRUE) // success! { // now that the document is loaded, we need to initialize the root pointer hr = m_XMLDoc->get_documentElement(&m_XMLBase); Debug(hr); } } CXMLProfile::~CXMLProfile() { //m_XMLDoc->save(COleVariant("c:\\Mach3\\Test.xml")); hr = m_XMLDoc->save(COleVariant(ProfileName)); Debug(hr); //m_XMLDoc->Release(); // release document regardless of whether save worked //m_XMLDoc = NULL; // release DOM CoUninitialize(); } void CXMLProfile::Debug(HRESULT hr) { if (FAILED(hr)) { _com_error er(hr); MessageBox(NULL, er.ErrorMessage(), "Error - Debug", MB_OK); }; } void CXMLProfile::SetProfileString(CString section, CString entry, CString value) { p_Elem = GetEntry(section, entry, true); p_Elem->put_text(CComBSTR(value)); p_Elem->Release(); } CString CXMLProfile::GetProfileString(CString section, CString entry, CString value) { CComBSTR szContent; p_nEntry = GetEntry(section, entry); if (p_nEntry == NULL) return value; p_nEntry->get_text(&szContent); if (szContent == CComBSTR("")) { p_nEntry->get_parentNode(&p_nSec); p_nSec->removeChild(p_nEntry, NULL); p_nEntry->Release(); p_nSec->Release(); return value; } p_nEntry->Release(); return CString(szContent); } IXMLDOMNode * CXMLProfile::GetEntry(LPCTSTR lpszSection, LPCTSTR lpszEntry, bool create) { m_XMLBase->selectSingleNode(CComBSTR(lpszSection), &p_nSec); if (p_nSec == NULL) { if (create) { m_XMLDoc->createElement(CComBSTR(lpszSection), &p_element); m_XMLBase->appendChild(p_element, &p_nSec); p_element->Release(); m_XMLDoc->createElement(CComBSTR(lpszEntry), &p_element); p_nSec->appendChild(p_element, &p_nEntry); p_element->Release(); p_nResult = p_nEntry; return p_nResult; } else return NULL; } else { p_nSec->selectSingleNode(CComBSTR(lpszEntry), &p_nEntry); if (p_nEntry == NULL) { if (create) { m_XMLDoc->createElement(CComBSTR(lpszEntry), &p_element); p_nSec->appendChild(p_element, &p_nEntry); p_element->Release(); return p_nEntry; } else return NULL; } else { p_nSec->Release(); return p_nEntry; } } } which is used like so:
DevProf = new CXMLProfile(); DevProf->SetProfileString("Test-Section", "Test", "Blah"); delete DevProf; when I modify the code to save the file in a new location and inspect the file using a text editor I find the expected changes, yet when trying to save to the original location and inspect the file, I find no changes.
I think what is happening is that the plugin is saving the changes to the original filed when the cleanup routine is called, then after that the main thread executes its cleanup routine and overwrites the file, hence no changes.
I think that somehow the main thread and the plugin are using different server instances to work with the files, and that the change in compiler/associated header/library files is the reason.
so my questions boil down to:
1) could a different 'bitness' of the server cause the issues I'm seeing
2) how can I check the 'bitness' of the server in use
3) how can I control the bitness of the server that is initiated
I have tried using alternate values from CLSCTX in place of CLSCTX_INPROC_SERVER such as:CLSCTX_INPROC_HANDLERCLSCTX_LOCAL_SERVERCLSCTX_INPROC_SERVER16
and I also tried bitwise OR'ing CLSCTX_ACTIVATE_32_BIT_SERVER with CLSCTX_INPROC_SERVER but for all of these combinations I got a Class not registered error
Any advice on how to check this through would be appreciated.
No comments:
Post a Comment