Web Services - C++ - VS 2005

When I add a Web Service in C# - no problem.
When I use C++ in VS 2005 I get:

_CE_ACTIVEX was not defined because this Windows CE SDK does not have DCOM.

_CE_ACTIVEX could be caused to be defined by defining _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA, but it is recommended that this be done only for single-threaded apps.

_ATL_NO_HOSTING was defined because _CE_ACTIVEX was not defined.

So I define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA

My question is - what is different about C# that I don't get the error.

If I create and call the Web Service from a thread I create would this be good thing?

[652 byte] By [Jraven] at [2008-2-4]
# 1
Using C++, creating and calling a web service from any thread, so as the calling thread is always the thread that created it, is fine (i.e. the existence of multiple threads aren't the problem; calling into instances of object that are not thread safe from threads other then the which created them is the problem).

C# uses the web service facilities of the .Net Compact Framework, while C++ uses ATL, and ATL primarly deals with platform differences at compile time rather then runtime.

JoshHeitzman-MSFT at 2007-9-8 > top of Msdn Tech,Smart Device Development,Smart Devices General...
# 2
Thanks - I understand now.

Is it possible to use the Web Service that I can create in VS 2005 under CPP?

The problem I had was that after doing the CoInitializeEx, I can not find the
information I need to do the CreateInstance in the set of files created
by the Web Service.

It gets setup automatically with C# or VB (in some magical way).

Anyway below is the header file created by the 'Add Web Reference' wizzard.
Do you know a way I can get the info from this to do a CreateInstance.

When I try to get a quote:
CComBSTR bstrResponse;
hr = service.GetQuote(CComBSTR(L"INTC"), &bstrResponse);
I get a "Class Not Registered" Error.
Which is true - I didn't register it, nor did I in the C# version.
In C#, I did not need to do the CoInitialize either.
I guess it does it when it sees you are using a Web Reference?
Maybe C#, it is more integrated with the Web Reference and does it for you?

Thanks

- John

webservicexwww.h
__

//
// sproxy.exe generated file
// do not modify this file
//
// Created: 06/10/2005@20:56:58
//

#pragma once

#if !defined(_WIN32_WINDOWS) && !defined(_WIN32_WINNT) && !defined(_WIN32_WCE)
#pragma message("warning: defining _WIN32_WINDOWS = 0x0410")
#define _WIN32_WINDOWS 0x0410
#endif

#include <atlsoap.h>

namespace StockQuote
{

template <typename TClient = CSoapSocketClientT<> >
class CStockQuoteT :
public TClient,
public CSoapRootHandler
{
protected:

const _soapmap ** GetFunctionMap();
const _soapmap ** GetHeaderMap();
void * GetHeaderValue();
const wchar_t * GetNamespaceUri();
const char * GetServiceName();
const char * GetNamespaceUriA();
HRESULT CallFunction(
void *pvParam,
const wchar_t *wszLocalName, int cchLocalName, size_t nItem);
HRESULT GetClientReader(ISAXXMLReader **ppReader);

public:

HRESULT __stdcall QueryInterface(REFIID riid, void **ppv)
{

if (ppv == NULL)
{
return E_POINTER;
}

*ppv = NULL;

if (InlineIsEqualGUID(riid, IID_IUnknown) ||
InlineIsEqualGUID(riid, IID_ISAXContentHandler))
{
*ppv =
static_cast<ISAXContentHandler *>(this);
return S_OK;
}

return E_NOINTERFACE;

}

ULONG __stdcall AddRef()

{
return 1;
}

ULONG __stdcall Release()

{
return 1;
}

CStockQuoteT(ISAXXMLReader *pReader = NULL)
:TClient(_T(
"http://www.webservicex.net/StockQuote.asmx"))
{
SetClient(
true);
SetReader(pReader);
}

~CStockQuoteT()
{
Uninitialize();
}

void Uninitialize()
{
UninitializeSOAP();
}

HRESULT GetQuote(
BSTR symbol,
BSTR* GetQuoteResult
);
};

typedef CStockQuoteT<> CStockQuote;

struct __CStockQuote_GetQuote_struct
{
BSTR symbol;
BSTR GetQuoteResult;
};

extern __declspec(selectany) const _soapmapentry __CStockQuote_GetQuote_entries[] =
{

{
0x150C4A36,
"symbol",
L"symbol",
sizeof("symbol")-1,
SOAPTYPE_STRING,
SOAPFLAG_NONE | SOAPFLAG_IN | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL | SOAPFLAG_NULLABLE,
offsetof(__CStockQuote_GetQuote_struct, symbol),
NULL,
NULL,
-1,
},
{
0xADEDE4CD,
"GetQuoteResult",
L"GetQuoteResult",
sizeof("GetQuoteResult")-1,
SOAPTYPE_STRING,
SOAPFLAG_NONE | SOAPFLAG_OUT | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL | SOAPFLAG_NULLABLE,
offsetof(__CStockQuote_GetQuote_struct, GetQuoteResult),
NULL,
NULL,
-1,
},
{ 0x00000000 }
};

extern __declspec(selectany) const _soapmap __CStockQuote_GetQuote_map =
{
0xE0A16C5D,
"GetQuote",
L"GetQuoteResponse",
sizeof("GetQuote")-1,
sizeof("GetQuoteResponse")-1,
SOAPMAP_FUNC,
__CStockQuote_GetQuote_entries,
sizeof(__CStockQuote_GetQuote_struct),
1,
-1,
SOAPFLAG_NONE | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL,
0x8EAC1FF6,
"http://www.webserviceX.NET/",
L"http://www.webserviceX.NET/",
sizeof("http://www.webserviceX.NET/")-1
};

extern __declspec(selectany) const _soapmap * __CStockQuote_funcs[] =
{
&__CStockQuote_GetQuote_map,
NULL
};

template <typename TClient>
inline HRESULT CStockQuoteT<TClient>::GetQuote(
BSTR symbol,
BSTR* GetQuoteResult
)
{
if ( GetQuoteResult == NULL )
return E_POINTER;

HRESULT __atlsoap_hr = InitializeSOAP(NULL);
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_INITIALIZE_ERROR);
return __atlsoap_hr;
}

CleanupClient();

CComPtr<IStream> __atlsoap_spReadStream;
__CStockQuote_GetQuote_struct __params;
memset(&__params, 0x00, sizeof(__params));
__params.symbol = symbol;

__atlsoap_hr = SetClientStruct(&__params, 0);
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_OUTOFMEMORY);
goto __skip_cleanup;
}

__atlsoap_hr = GenerateResponse(GetWriteStream());
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_GENERATE_ERROR);
goto __skip_cleanup;
}

__atlsoap_hr = SendRequest(_T("SOAPAction: \"http://www.webserviceX.NET/GetQuote\"\r\n"));
if (FAILED(__atlsoap_hr))
{
goto __skip_cleanup;
}
__atlsoap_hr = GetReadStream(&__atlsoap_spReadStream);
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_READ_ERROR);
goto __skip_cleanup;
}

// cleanup any in/out-params and out-headers from previous calls
Cleanup();
__atlsoap_hr = BeginParse(__atlsoap_spReadStream);
if (FAILED(__atlsoap_hr))
{
SetClientError(SOAPCLIENT_PARSE_ERROR);
goto __cleanup;
}

*GetQuoteResult = __params.GetQuoteResult;
goto __skip_cleanup;

__cleanup:
Cleanup();
__skip_cleanup:
ResetClientState(true);
memset(&__params, 0x00, sizeof(__params));
return __atlsoap_hr;
}

template <typename TClient>
ATL_NOINLINE inline const _soapmap ** CStockQuoteT<TClient>::GetFunctionMap()
{
return __CStockQuote_funcs;
}

template <typename TClient>
ATL_NOINLINE inline const _soapmap ** CStockQuoteT<TClient>::GetHeaderMap()
{
static const _soapmapentry __CStockQuote_GetQuote_atlsoapheader_entries[] =
{
{ 0x00000000 }
};

static const _soapmap __CStockQuote_GetQuote_atlsoapheader_map =
{
0xE0A16C5D,
"GetQuote",
L"GetQuoteResponse",
sizeof("GetQuote")-1,
sizeof("GetQuoteResponse")-1,
SOAPMAP_HEADER,
__CStockQuote_GetQuote_atlsoapheader_entries,
0,
0,
-1,
SOAPFLAG_NONE | SOAPFLAG_PID | SOAPFLAG_DOCUMENT | SOAPFLAG_LITERAL,
0x8EAC1FF6,
"http://www.webserviceX.NET/",
L"http://www.webserviceX.NET/",
sizeof("http://www.webserviceX.NET/")-1
};


static const _soapmap * __CStockQuote_headers[] =
{
&__CStockQuote_GetQuote_atlsoapheader_map,
NULL
};

return __CStockQuote_headers;
}

template <typename TClient>
ATL_NOINLINE inline void * CStockQuoteT<TClient>::GetHeaderValue()
{
return this;
}

template <typename TClient>
ATL_NOINLINE inline const wchar_t * CStockQuoteT<TClient>::GetNamespaceUri()
{
return L"http://www.webserviceX.NET/";
}

template <typename TClient>
ATL_NOINLINE inline const char * CStockQuoteT<TClient>::GetServiceName()
{
return NULL;
}

template <typename TClient>
ATL_NOINLINE inline const char * CStockQuoteT<TClient>::GetNamespaceUriA()
{
return "http://www.webserviceX.NET/";
}

template <typename TClient>
ATL_NOINLINE inline HRESULT CStockQuoteT<TClient>::CallFunction(
void *,
const wchar_t *, int,
size_t)
{
return E_NOTIMPL;
}

template <typename TClient>
ATL_NOINLINE inline HRESULT CStockQuoteT<TClient>::GetClientReader(ISAXXMLReader **ppReader)
{
if (ppReader == NULL)
{
return E_INVALIDARG;
}

CComPtr<ISAXXMLReader> spReader = GetReader();
if (spReader.p != NULL)
{
*ppReader = spReader.Detach();
return S_OK;
}
return TClient::GetClientReader(ppReader);
}

} // namespace StockQuote

Jraven at 2007-9-8 > top of Msdn Tech,Smart Device Development,Smart Devices General...
# 3

hi ,

I'm also facing some issue do you have any clue to solve this issue ... i am writing vc++ smartdevice win32 smartphone application . i need to invoke couple of web method in the application flow. i added web reference so it's created me proxy class using sproxy.exe , and i created instance like below...

CServiceT<CSoapSocketClientT<ZEvtSyncSocket>> ObjWeb;
ObjWeb.AddNumbers(45,22,&intResult); {AddNumber web method takes 3 arg..}

when i invoke this method it's failed to create(ATLSOAP: CSoapRootHandler::InitializeSOAP -- failed to get SAXXMLReader.) do you have any idea why it get's failed ...

Thanks ,

Jayakumar A

JayakumarA at 2007-9-8 > top of Msdn Tech,Smart Device Development,Smart Devices General...
# 4

Try this.

::CoInitialize(NULL);

ObjWeb.SetProxy();

// Do your stuff

ObjWeb.Uninitialize();

::CoUninitialize();

HarshModi-MSFT at 2007-9-8 > top of Msdn Tech,Smart Device Development,Smart Devices General...