- custommarshaling01_src.zip
- BasicSample01
- Clients
- VCConsoleClient01
- VCConsoleClient02
- VCConsoleClient03
- Implementations
- BasicSample01InterfacesImpl
- Interfaces
- BasicSample01Interfaces
- utilities
|
#ifndef UTILITIES_H
#define UTILITIES_H
#include <windows.h>
#include <vector>
using namespace std;
typedef vector<HANDLE> HANDLE_VECTOR;
DWORD ThreadMsgWaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds);
DWORD ThreadMsgWaitForMultipleObjects
(
DWORD dwCount,
LPHANDLE pHandles,
BOOL bWaitAll,
DWORD dwMilliseconds
);
template <class SmartPtrClass>
bool _CoCreateInstance(LPCTSTR lpszProgID, SmartPtrClass& spSmartPtrReceiver)
{
HRESULT hrRetTemp = S_OK;
_bstr_t bstProgID(lpszProgID);
CLSID clsid;
bool bRet = false;
hrRetTemp = CLSIDFromProgID
(
(LPCOLESTR)bstProgID, //Pointer to the ProgID
(LPCLSID)&clsid //Pointer to the CLSID
);
if (hrRetTemp == S_OK)
{
hrRetTemp = spSmartPtrReceiver.CoCreateInstance(clsid);
if (SUCCEEDED(hrRetTemp))
{
bRet = true;
}
else
{
bRet = false;
}
}
return bRet;
}
/* LowLevelInProcMarshalInterface() uses low-level APIs */
/* CreateStreamOnHGlobal(), CoMarshalInterface(), and IStream */
/* methods to perform interface pointer marshalling across */
/* apartments in a process. */
/* */
template <typename T>
LPSTREAM LowLevelInProcMarshalInterface(T* pInterface, REFIID riid)
{
IUnknown* pIUnknown = NULL;
IStream* pIStreamRet = NULL;
/* QI the original interface pointer for its IUnknown interface. */
pInterface -> QueryInterface (IID_IUnknown, (void**)&pIUnknown);
/* Once we get the IUnknown pointer, we serialize it into a stream of bytes. */
if (pIUnknown)
{
/* Create a Stream Object which will reside in global memory. */
/* We set the first parameter to NULL, hence indicating that */
/* we want CreateStreamOnHGlobal() to internally allocate */
/* a new shared memory block of size zero. */
/* The second parameter is set to TRUE so that when the returned*/
/* stream object is Release()'d, the global memory will also be */
/* freed. */
::CreateStreamOnHGlobal
(
0,
TRUE,
&pIStreamRet
);
if (pIStreamRet)
{
LARGE_INTEGER li = { 0 };
/* We use the new stream object to store the marshalling data */
/* of spISimpleCOMObject2. */
/* The use of MSHCTX_INPROC indicates that the unmarshaling */
/* of the data in the stream will be done in another apartment*/
/* in the same process. */
::CoMarshalInterface
(
pIStreamRet,
riid,
(IUnknown*)pIUnknown,
MSHCTX_INPROC,
NULL,
MSHLFLAGS_NORMAL
);
/* Always reset the stream to the beginning.*/
pIStreamRet -> Seek(li, STREAM_SEEK_SET, NULL);
}
pIUnknown -> Release();
pIUnknown = NULL;
}
return pIStreamRet;
}
/* LowLevelInProcUnmarshalInterface() uses low-level APIs */
/* CoUnmarshalInterface(), CoReleaseMarshalData(), and */
/* IStream methods to perform interface pointer unmarshalling */
/* for an apartment in a process. */
/* */
template <typename T>
void LowLevelInProcUnmarshalInterface(LPSTREAM pIStream, REFIID riid, T** ppInterfaceReceiver)
{
/* Deserialize the byte contents of the IStream object */
/* into an actual interface pointer to be used only */
/* within this thread. */
/* */
/* The interface pointer will not be a direct pointer. */
/* It will be a proxy to the original pointer. */
if (pIStream)
{
LARGE_INTEGER li = { 0 };
/* Make sure stream pointer is at the beginning of the stream. */
pIStream -> Seek(li, STREAM_SEEK_SET, NULL);
if
(
::CoUnmarshalInterface
(
pIStream, //Pointer to the stream
riid, //Reference to the identifier of the interface
(void **)ppInterfaceReceiver //Address of output variable that receives the
// interface pointer requested in riid
) != S_OK
)
{
/* Since unmarshalling has failed, we call */
/* CoReleaseMarshalData() to destroys the */
/* previously marshaled data packet contained*/
/* in pIStream. */
::CoReleaseMarshalData(pIStream);
}
/* When pIStream is Release()'d the underlying global memory*/
/* used to store the bytes of the stream is also freed. */
pIStream -> Release();
pIStream = NULL;
}
}
#endif
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Lim Bio Liong is a Specialist at a leading Software House in Singapore.
Bio has been in software development for over 10 years. He specialises in C/C++ programming and Windows software development.
Bio has also done device-driver development and enjoys low-level programming. Bio has recently picked up C# programming and has been researching in this area.