六 172009
前几天被人问起这个问题:怎么在C语言中使用MSXML。本来以为蛮简单的,因为C语言里也支持指针和结构,代码没什么地方需要改的,结果发现不然……
先来看一下C++里是怎么写的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #import "msxml6.dll" raw_interfaces_only #include <cstdio> using namespace std; #include "windows.h" int main(){ CoInitialize(NULL); MSXML2::IXMLDOMDocument2* doc = NULL; CoCreateInstance(__uuidof(MSXML2::DOMDocument60), NULL, CLSCTX_INPROC_SERVER, __uuidof(MSXML2::IXMLDOMDocument2), (LPVOID*)&doc); VARIANT_BOOL result; doc->loadXML(_bstr_t(L""), &result); BSTR outxml = NULL; doc->get_xml(&outxml); wprintf(L"xml = %s\n", outxml); ::SysFreeString(outxml); doc->Release(); CoUninitialize(); return 0; } |
这里为了简洁,直接引用了”windows.h”,并且没有检查函数的返回值。
代码里一些东西是C语不支持的:
- 预编译指令#import
- 命名空间(Namespace),当然这个不是很重要
- 关键字__uuidof也不支持
- 实际上doc->Release()这样的函数调用也不是支持的,详见下面的代码
于是在C语言中就变成了这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #define COBJMACROS #include "msxml6.h" #include "windows.h" #include "stdio.h" int main(){ IXMLDOMDocument2 *doc; VARIANT_BOOL loaded; BSTR inxml = SysAllocString(L""); BSTR outxml = NULL; CoInitialize(NULL); CoCreateInstance(&CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (LPVOID*)&doc); IXMLDOMDocument_loadXML(doc, inxml, &loaded); IXMLDOMDocument_get_xml(doc, &outxml); wprintf(L"XML = %s\n", outxml); SysFreeString(inxml); SysFreeString(outxml); IXMLDOMDocument_Release(doc); CoUninitialize(); return 0; } |
最大的改动是定义了COBJMACROS,这样可以使用另外一种的函数调用,比如原来的doc->get_xml(&outxml);变成了IXMLDOMDocument_get_xml(doc, &outxml);,实际上IXMLDOMDocument_get_xml(a,b)是一个宏,它会被展开成a->vtbl->get_xml(a,b)。至于COBJMACROS具体是什么意思,我也没找到文档-_-
不过无论如何,在C语言中是可以使用MSXML的,并且和C++中没什么大区别……
您还可能感兴趣的日志: