PRB: Compiler Errors When You Use #import with XML in Visual C++ .NET

Article translations Article translations
Article ID: 316317 - View products that this article applies to.
This article was previously published under Q316317
Expand all | Collapse all

SYMPTOMS

When you use MSXML parser dynamic-link libraries (DLLs) such as Msxml.dll, Msxml2.dll, Msxml3.dll, or Msxml4.dll to compile a Visual C++ .NET project with #import, you may receive the following compiler error messages:
c:\sample\test.cpp(12) : error C2872: 'IXMLDOMDocumentPtr' : ambiguous symbol

could be 'c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\comdefsp.h(1228) : _com_ptr_t<_IIID> IXMLDOMDocumentPtr' with [ _IIID=_com_IIID<IXMLDOMDocument,& _GUID_2933bf81_7b36_11d2_b20e_00c04f983e60> ]

or 'c:\sample\Debug\msxml3.tlh(226) : MSXML2::IXMLDOMDocumentPtr'
-or-

c:\sample\test.cpp(16) : error C2039: 'async' : is not a member of 'IXMLDOMDocument' c:\Program Files\Microsoft Visual Studio .NET\Vc7\PlatformSDK\Include\MsXml.h(1845) : see declaration of 'IXMLDOMDocument'
-or-

c:\sample\test.cpp(27) : error C2660: 'IXMLDOMDocument::load' : function does not take 1 parameters
You may also see other C2039 and C2660 errors in the output. The workaround that is described in the following Knowledge Base article does not resolve the compiler errors with Microsoft Visual C++ .NET:
269194 PRB: Compiler Errors When You Use #import with XML

CAUSE

The "ambiguous symbol" error occurs when a smart pointer interface definition such as IXMLDOMDocumentPtr is defined in both the MSXML2 namespace (through #import) and the global namespace (through Msxml.h), so that the symbol is ambiguous. When the compiler resolves the interfaces, the compiler looks first in Msxml.h, which has different signatures than those that #import generates.

RESOLUTION

To resolve this problem, use the "typelib" namespace with MSXML parser DLLs to prefix the interface pointers and globally unique identifiers (GUIDs). To avoid the errors, explicitly qualify the interface declaration and GUIDs to remove the ambiguity, as follows:
#include <stdio.h>
#import <msxml4.dll>

void dump_com_error(_com_error &e);

int main(int argc, char* argv[]) 
{
	CoInitialize(NULL);
	try 
	{
		MSXML2::IXMLDOMDocumentPtr pXMLDoc = NULL;
		HRESULT hr = pXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));
		pXMLDoc->async =  VARIANT_FALSE; // default - true,

		hr = pXMLDoc->loadXML("<tag1>Abcdef</tag1>");
		//hr = pXMLDoc->load("myData.xml");
		
		if (hr != VARIANT_TRUE)
		{
			MSXML2::IXMLDOMParseErrorPtr  pError;
			pError = pXMLDoc->parseError;
			_bstr_t parseError =_bstr_t("At line ")+ _bstr_t(pError->Getline()) + _bstr_t("\n")+ _bstr_t(pError->Getreason());
			MessageBox(NULL,parseError, "Parse Error",MB_OK);
			return 0;
		}
		else 
		{
			MessageBox(NULL,pXMLDoc->xml, "Loading Succeeded",MB_OK);
		}
	}
	catch(_com_error &e) 
	{
		dump_com_error(e);
	}
	return 0;
}

void dump_com_error(_com_error &e)
{
	printf("Error\n");
	printf("\a\tCode = %08lx\n", e.Error());
	printf("\a\tCode meaning = %s", e.ErrorMessage());
	_bstr_t bstrSource(e.Source());
	_bstr_t bstrDescription(e.Description());
	printf("\a\tSource = %s\n", (LPCSTR) bstrSource);
	printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription);
}
				
NOTE: Msxml.dll uses the "MSXML" namespace. Msxml2.dll, Msxml3.dll and Msxml4.dll use the "MSXML2" namespace.

STATUS

This behavior is by design.

MORE INFORMATION

The following is a typical code sample that shows the use of the MSXML parser with Visual C++:
#import "c:\winnt\system32\msxml4.dll" 
using namespace MSXML2;

int main(int argc, char* argv[])
{
	IXMLDOMDocumentPtr dom(__uuidof(DOMDocument40));
				
The #import feature includes a file named Comdef.h that indirectly includes Urlmon.h, which in turn includes Msxml.h. This is necessary because the end of Comdef.h includes Comdefsp.h, which defines many common GUIDs and XML interfaces. For example, the following sample causes Msxml.h to be included before the .tlh file:
_COM_SMARTPTR_TYPEDEF(IXMLDocument, __uuidof(IXMLDocument));
_COM_SMARTPTR_TYPEDEF(IXMLElement, __uuidof(IXMLElement));
_COM_SMARTPTR_TYPEDEF(IXMLElementCollection, __uuidof(IXMLElementCollection));
_COM_SMARTPTR_TYPEDEF(IXMLElementNotificationSink, __uuidof(IXMLElementNotificationSink));
_COM_SMARTPTR_TYPEDEF(IXMLError, __uuidof(IXMLError));
				
With the MSXML 4.0 parser file, the Msxml4.tlh file is generated from #import.

Properties

Article ID: 316317 - Last Review: June 28, 2003 - Revision: 2.1
APPLIES TO
  • Microsoft XML Parser 2.0
  • Microsoft XML Parser 2.5
  • Microsoft XML Parser 2.6
  • Microsoft XML Parser 3.0
  • Microsoft XML Core Services 4.0
  • Microsoft Visual C++ .NET 2002 Standard Edition
  • Microsoft Visual C++ .NET 2003 Standard Edition
Keywords: 
kbmsxmlnosweep kbprb KB316317

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com