Ik ben bezig met het maken van een client-server applicatie en het leek mij mede met oog op de toekomstige uitbreidbaarheid en het koppelen van client software die door anderen gemaakt is handig om voor de communicatie tussen de client en de server XML te gebruiken. XML genereren gaat prima, XML parsen uit een file gaat ook uitstekend, maar zodra ik zelf een ISequentialInputStream implementeer om te gebruiken als 'voer' voor de XML parser (ik maak gebruik van SAX2) gaan er dingen fout.
Onderstaande code geeft de volgende output:
Weet een van jullie wat ik fout doe?
PS: Sorry voor het enorm lange bericht
Onderstaande code geeft de volgende output:
Er staan dus 2 AddRefs in de code, en 3 Releases. Nou is mij altijd geleerd dat het aantal AddRef aanroepen gelijk is aan het aantal Release aanroepen.MYContent
MyReader
MyReaderImpl
AddRef
AddRef
<?xml version="1.0" ?>
<dicomfile>
<header>
<encoding>
</encoding>
<length>
</length>
</header>
</dicomfile>
Release
Release
Release
~MyReaderImpl
~MyReader
~MYContent
Weet een van jullie wat ik fout doe?
code:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
| // XMLRead.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "MyContent.h"
#include "SAXErrorHandlerImpl.h"
class MyReader : public ISequentialStream
{
public:
MyReader() { printf("MyReader\n"); };
virtual ~MyReader() { printf("~MyReader\n"); };
long __stdcall QueryInterface(const struct _GUID &,void ** );
unsigned long __stdcall AddRef(void);
unsigned long __stdcall Release(void);
virtual HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG * pcbRead) = 0;
virtual HRESULT STDMETHODCALLTYPE Write(const void *pv, ULONG cb, ULONG * pcbWritten) = 0;
};
long __stdcall MyReader::QueryInterface(const struct _GUID &riid,void ** ppvObject)
{
if (__uuidof(ISequentialStream) == riid)
{
*ppvObject = (ISequentialStream *)this;
return S_OK;
}
return E_NOINTERFACE;
}
unsigned long __stdcall MyReader::AddRef()
{
printf("AddRef\n");
return 0;
}
unsigned long __stdcall MyReader::Release()
{
printf("Release\n");
return 0;
}
class MyReaderImpl : public MyReader
{
public:
MyReaderImpl()
{
printf("MyReaderImpl\n");
m_nOffset = 0;
pData = "<?xml version=\"1.0\" standalone=\"yes\" ?>" \
"<dicomfile>" \
"<header>" \
" <encoding>base-64</encoding>" \
" <length>120</length>" \
"</header>" \
"</dicomfile>";
m_nDataLen = strlen(pData);
}
~MyReaderImpl()
{
printf("~MyReaderImpl\n");
}
HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead)
{
int nToDo = cb;
if ((m_nOffset + nToDo) > m_nDataLen) nToDo = m_nDataLen - m_nOffset;
memcpy(pv, &pData[m_nOffset], nToDo);
m_nOffset += nToDo;
*pcbRead = nToDo;
if (nToDo) return S_OK;
return S_FALSE;
};
HRESULT STDMETHODCALLTYPE Write(const void *pv, ULONG cb, ULONG *pcbWritten)
{
return S_OK;
}
private:
char *pData;
int m_nDataLen;
int m_nOffset;
};
int main(int argc, char* argv[])
{
CoInitialize(NULL);
{
MyContent pMC;
MyReaderImpl pMR;
ISAXXMLReaderPtr pReader = NULL;
pReader.CreateInstance(CLSID_SAXXMLReader40);
HRESULT hr = pReader->putContentHandler(&pMC);
CComVariant Out(&pMR);
hr = pReader->parse(Out);
}
CoUninitialize();
return 0;
} |
PS: Sorry voor het enorm lange bericht