/////////////////////////////////////////////////////////////// // client.cpp - client for outproc1 // // ver 1.2 // // // // Platform: Dell XPs B1000r, Windows 2000 Professional // // Application: Demonstration for CSE791 - Distrib. Objs // // Author: Jim Fawcett, Syracuse Univ, CST 2-187 // // (315) 443-3948, jfawcett@twcny.rr.com // // Derived From: Eddon & Eddon, Inside Distributed COM, // // Microsoft Press, 1998 // /////////////////////////////////////////////////////////////// #define _WIN32_DCOM #include #include "Component\component.h" using namespace std; void main() { cout << "\n Client of Component Providing a Variety of Interface Types " << "\n ============================================================" << endl; cout << "\n Calling CoInitialize()"; cout.flush(); CoInitialize(NULL); DWORD ID = GetCurrentThreadId(); cout << "\n\n client STA thread ID is: " << ID << endl; IUnknown *pUnknown; IBaseTypes *pBaseTypes; IStrings *pStrings; IPtrs *pPtrs; IArrays *pArrays; IStruct *pStruct; cout << "\n Calling CoCreateInstance() "; cout.flush(); CoCreateInstance( CLSID_Interfaces, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pUnknown ); if(pUnknown == NULL) { cout << "\n CoCreateInstance failed\n" << endl; return; } // HRESULT hr; cout << "\n ========================================================="; cout << "\n Calling QueryInterface() for IBaseTypes on " << pUnknown; cout << "\n ========================================================="; cout.flush(); hr = pUnknown->QueryInterface(IID_IBaseTypes, (void**)&pBaseTypes); if(FAILED(hr)) { cout << "QueryInterface FAILED\n" << endl; return; } cout << "\n pBaseTypes = " << pBaseTypes << endl; cout << "\n Calling BaseTypes([in] INT, [in] DOUBLE, [out] WCHAR*)"; WCHAR WideChar; hr = pBaseTypes->BaseTypes(4, -3.5e-5, &WideChar); if(FAILED(hr)) { cout << "\n call to BaseTypes failed\n\n"; pBaseTypes->Release(); pUnknown->Release(); return; } CHAR ch = static_cast(WideChar); cout << "\n returned character is: " << ch << endl; cout << "\n Calling Release() for pBaseTypes"; cout.flush(); hr = pBaseTypes->Release(); // cout << "\n ========================================================="; cout << "\n Calling QueryInterface() for IStrings on " << pUnknown; cout << "\n ========================================================="; cout.flush(); hr = pUnknown->QueryInterface(IID_IStrings, (void**)&pStrings); if(FAILED(hr)) { cout << "\n QueryInterface FAILED\n" << endl; pUnknown->Release(); return; } cout << "\n pStrings = " << pStrings << endl; cout << "\n Calling Strings([in] WCHAR *sIn, [out] WCHAR **sOut)"; WCHAR *recvString=NULL; WCHAR *sendString = L"\"a string from client\""; const int MAX = 50; char buffer[MAX]; wcstombs(buffer,sendString,MAX); cout << "\n sending " << buffer; cout.flush(); hr = pStrings->Strings(sendString,&recvString); if(FAILED(hr)) { cout << "\n call to Strings failed\n\n"; pStrings->Release(); pUnknown->Release(); } if(recvString == NULL) { cout << "\n invalid return string" << endl; } else { wcstombs(buffer,recvString,MAX); cout << "\n received \"" << buffer << "\""; cout.flush(); } cout << "\n Freeing string memory allocated in component\n"; CoTaskMemFree(recvString); // cout << "\n Calling BStringIn([in] BSTR bstr)"; char *pC = "These are chars in a BSTR going to component"; int numChars = strlen(pC); OLECHAR *BSbuffer = new OLECHAR[numChars+1]; mbstowcs(BSbuffer,pC,numChars+1); BSTR bstr = SysAllocString(BSbuffer); cout << "\n Sending: " << pC; cout.flush(); hr = pStrings->BStringIn(bstr); if(FAILED(hr)) { cout << "\n call to BStringIn failed\n\n"; pStrings->Release(); pUnknown->Release(); } cout << '\n'; SysFreeString(bstr); cout << "\n Calling BStringOut([out] BSTR *bstr)"; hr = pStrings->BStringOut(&bstr); OLECHAR *pOC = (OLECHAR*)bstr; numChars = SysStringByteLen(bstr); char *CBuffer = new char[numChars+1]; wcstombs(CBuffer,pOC,numChars+1); cout << "\n Received: " << CBuffer << '\n'; delete [] CBuffer; SysFreeString(bstr); cout << "\n Calling Release() for pStrings"; cout.flush(); hr = pStrings->Release(); // cout << "\n ========================================================="; cout << "\n Calling QueryInterface() for IPtrs on " << pUnknown; cout << "\n ========================================================="; cout.flush(); hr = pUnknown->QueryInterface(IID_IPtrs, (void**)&pPtrs); if(FAILED(hr)) { cout << "QueryInterface FAILED\n" << endl; pUnknown->Release(); return; } cout << "\n pPtrs = " << pPtrs << endl; cout << "\n Calling PutPtrRef([in,out,ref] INT *pIn)"; INT demoIn = 5; cout << "\n sending pointer to value: " << demoIn; hr = pPtrs->PutPtrRef(&demoIn); if(FAILED(hr)) { cout << "\n\n call to PutPtrRef failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << "\n Received doubled value : " << demoIn << endl; cout << "\n Calling PutPtrUnique([in,unique] INT *pInOut)"; INT demoUnique = 25; INT *pUnique = &demoUnique; cout << "\n sending pointer to value: " << *pUnique; hr = pPtrs->PutPtrUnique(pUnique); if(FAILED(hr)) { cout << "\n\n call to PutPtrUnique failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << "\n Received tripled value : " << *pUnique; // pUnique = NULL; INT *pInOut = pUnique; cout << "\n sending null pointer: " << pUnique; cout.flush(); hr = pPtrs->PutPtrUnique(pInOut); if(FAILED(hr)) { cout << "\n\n call to PutPtrUnique failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << endl; cout << "\n Calling PutPtrPtr([in,ptr] INT *pIn1, [in,ptr] INT *pIn2)"; INT demoPtr1 = 15; INT demoPtr2 = 25; cout << "\n sending pointers to values: " << demoPtr1 << " and " << demoPtr2; hr = pPtrs->PutPtrPtr(&demoPtr1,&demoPtr2); if(FAILED(hr)) { cout << "\n\n call to PutPtrPtr failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << "\n Received modified values: " << demoPtr1 << " and " << demoPtr2; cout << "\n sending two instances of same pointer to value: " << demoPtr1; hr = pPtrs->PutPtrPtr(&demoPtr1,&demoPtr1); if(FAILED(hr)) { cout << "\n\n call to PutPtrPtr failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << "\n Received modified value: " << demoPtr1 << endl; cout << "\n Calling Release() for pPtrs"; cout.flush(); hr = pPtrs->Release(); // cout << "\f"; cout << "\n ========================================================="; cout << "\n Calling QueryInterface() for IStruct on " << pUnknown; cout << "\n ========================================================="; cout.flush(); hr = pUnknown->QueryInterface(IID_IStruct, (void**)&pStruct); if(FAILED(hr)) { cout << "QueryInterface FAILED\n" << endl; pUnknown->Release(); return; } cout << "\n pStruct = " << pStruct << endl; cout << "\n Calling PutStruct([in] struct {int len; char *array;} )"; DemStruct ds; ds.array = (unsigned char*)("now is the hour"); ds.len = strlen((const char*)(ds.array)); hr = pStruct->PutStruct(&ds); if(FAILED(hr)) { cout << "\n\n call to PutStruct failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << "\n Calling GetStruct([out] DemStruct *pDS)"; hr = pStruct->GetStruct(&ds); if(FAILED(hr)) { cout << "\n\n call to GetStruct failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << "\n server returned struct with components:" << "\n len = " << ds.len << ", array = \"" << ds.array << "\""; cout << "\n freeing string memory allocated by server" << endl; CoTaskMemFree(ds.array); cout << "\n Calling Release() for pStruct"; cout.flush(); hr = pStruct->Release(); // cout << "\n ========================================================="; cout << "\n Calling QueryInterface() for IArrays on " << pUnknown; cout << "\n ========================================================="; cout.flush(); hr = pUnknown->QueryInterface(IID_IArrays, (void**)&pArrays); if(FAILED(hr)) { cout << "QueryInterface FAILED\n" << endl; pUnknown->Release(); return; } cout << "\n pArrays = " << pArrays << endl; cout << "\n Calling FixedArray(Arr[5])"; INT Arr[5] = { 0, 1, 2, 3, 4 }; hr = pArrays->FixedArray(Arr); if(FAILED(hr)) { cout << "\n\n call to FixedArray failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << "\n Calling ConformantArray(size=4,pD)"; int size = 4; DOUBLE *pD = new DOUBLE[size]; pD[0] = -0.5; pD[1] = -1.5; pD[2] = -2.5; pD[3] = -3.5; hr = pArrays->ConformantArray(size,pD); if(FAILED(hr)) { cout << "\n\n call to ConformantArray failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << "\n Calling OpenArray(size=10, len=4, first=2, pInt=array)"; size = 10; INT len = 4, first = 2; INT array[10] = { 0,1,2,3,4,5,6,7,8,9}; hr = pArrays->OpenArray(size,len,first,array); if(FAILED(hr)) { cout << "\n\n call to TwoDimArray failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } cout << endl; // /* cout << "\n Calling TwoDimArray(INT rows, INT cols, DOUBLE ***pppD)"; cout.flush(); INT r=4, c=5; DOUBLE **ppD; hr = pArrays->TwoDimArray(r,c,&ppD); if(FAILED(hr)) { cout << "\n\n call to TwoDimArray failed\n\n"; pPtrs->Release(); pUnknown->Release(); return; } int i, j; for(i=0; iRelease(); cout << "\n Calling Release() for pUnknown"; cout.flush(); hr = pUnknown->Release(); cout << "\n Calling CoUninitialize()\n" << endl; CoUninitialize(); }