The limit of the interface: COM requires the separation of the customer and server height, which has been implemented by the interface, but the problem is that the interface method only provides a limited number of data types. If the interface is iDispatch, our choice is more limited. Keep in mind that these restrictions, C objects can only be passed in the following cases: 1. Customers and services are compiled by VC; 2. They must have a common object definition, such as the same header file; 3. Pass C objects simplify the design of the application; 4. In a distributed environment, you need to pay attention to your COM must have remote activation, local / remote transparency, security demonstration. Below is an example: 1. Generate an ATL DLL server 2. Add a class inherited in the COBJECT. CSIMPLEOBJ: PUBLIC COBJECT
{
Declare_serial (csimpleobj)
PUBLIC:
// Constructor and Destructor
CSIMPLEOBJ ();
Virtual ~ csimpleObj ();
// Set the internal string void setString (CSTRING CSDATA);
// Used to serialize your data Virtual Void Serialize (CARCHIVE & AR);
// Display data void show ();
Private:
CSTRING M_STRDATA; // Define a string object} here;
// Write this Object to an archive
Void CsimpleObj :: Serialize (CARCHIVE & A)
{
COBJECT :: Serialize (AR);
IF (ar.doading ())
{
// Extract Data from Archive
Ar >> M_STRDATA;
}
Else
{
// Store Data Into Archive
Ar << m_strdata;
}
}
//Method to Display Data in this Object
Void CsimpleObj :: show ()
{
AfxMessageBox (M_STRDATA);
}
// Save a string in data member
Void CsimpleObj :: setString (CString CSData)
{
M_STRDATA = CSDATA;
}
6. Next We access objects through the Carchive, here is an additional CBLob.class CBLOB
{
PUBLIC:
CBLOB () {};
Virtual ~ cblob () {};
// Extract data from a cobject and load it Into a SafeArray.
SafeArray * load (COBJECT * POBJ);
// RE-CREATE AN Object from A SafeArray
Bool Expand (COBJECT * & POBJ, SAFEARRAY * PVAR);
Private:
}
// Extract Data from a cobject and use it to create a safect.
SafeArray * CBLOB :: Load (cobject * pobj)
{
CMemfile Memfile; // Memory File
// define the flag thing tells the archive WHETHER ITHHOULD
// load or store
Long lmode = carchive :: store | carchive :: bnoflushondelete; // Create the archive using the memory file
CARCHIVE AR (& Memfile, LMODE);
// m_pdocument is not available
Ar.m_pdocument = null;
// serialize the object Into the archive
ar.writeObject (potj);
// Close the archive - The data is now stored in Memfile
ar.close ();
// get the length (in bytes) of the memory file
Long Llen = Memfile.getLength ();
// DETACH the BUFFER AND CLOSE The File
Unsigned char * pmemdata = memfile.detach ();
// set Up SafeArray
SafeArray * PSA;
// Create a Safe Array to Store The Stream Data
PSA = SafeArrayCreateVector (VT_UI1, 0, LLEN);
// Pointers to Byte Arrays
Unsigned char * pdata = NULL;
// Get a Pointer to the Safe Array. Locks the array.
SafeAccessData (PSA, (void **) & pdata);
// Copy The Memory File Into The SafeArray
Memcpy (PDATA, PMEMDATA, LLEN);
// Clean Up buffer
Delete Pmemdata;
// Unlock Access to SafeArray
SafeArrayunaccessData (PSA);
// Return a Pointer to A SafeArray Allocated Here
Return PSA;
}
// RE-CREATE AN Object from A SafeArray
Bool CBLOB :: Expand (COBJECT * & RPOBJ, SAFEARRAY * PSA)
{
CMemfile Memfile; // Memory File for de-serailze
Long Llength; // Number of Bytes
Char * pbuffer; // buffer Pointer
// Lock Access To Array Data
SafearrayAccessData (PSA, (void **) & pbuffer;
// Get Number of elements in array. this is the number of bytes
LLENGTH = PSA-> Rgsabound-> CELEMENTS;
// attach the buffer to the memory file
Memfile.attach (UNSIGNED Char *) PBuffer, LLEngth;
// start at beginningning of buffer
Memfile.seektobegin ();
// Create An Archive with the attachmed memory file
Carchive Ar (& Memfile, Carchive :: Load | CARCHIVE :: Bnoflushondlete); // Document Pointer Is Not Used
Ar.m_pdocument = null;
// inflate the object and get the pointer
RPOBJ = ar.readObject (0);
// Close the archive
ar.close ();
// Note: PBuffer is freed when the saveRay is destroyed
// DETACH the BUFFER AND CLOSE The File
PBuffer = (char *) Memfile.detach ();
// Release The SafeArray Buffer
SafeArrayunaccessData (PSA);
Return True;
}
It is more suitable for our purposes here. It can accommodate complex multidimensional arrays. Here we only use a very simple array. But there is a problem with SafeArray, MIDL does not know this type, the easiest way It is a variant type. Next: 1. Generate a COM interface, 2. Generate a SafeArray object 3. Define 2 methods in the IDL file: [Helpstring ("Method setArray")] HRESULT STARRAY ([in] SafeArray unsigned Char); [Helpstring ("Method GetArray")] HRESULT GETARRAY ([OUT / *, RETVAL * /] SafeArray (unsigned char) * pdata); 4. Generate an MFC-based client to test IDL files such: interface IBolbData: IUnknown {[helpstring ( "method SetArray")] HRESULT SetArray ([in] SAFEARRAY (unsigned char) pData); [helpstring ( "method GetArray")] HRESULT GetArray ([out / *, retval * /] SAFEARRAY (unsigned char) * pData);}; // Sets object.STDMETHODIMP CBolbData :: SetArray (SAFEARRAY * pData) {AFX_MANAGE_STATE (AfxGetStaticModuleState ()) // create a dummy pointer of CSimpleObj CSimpleObj * dummy = NULL; / / create blob obect to expand / deserialize CBlob blob; // Init dummy object using safe array through this function blob.Expand ((CObject * &) dummy, pData); dummy-> Show (); // Call show functi on to test the object delete dummy;. // Delete the pointer return S_OK;.} // Creates Object and sends to client.STDMETHODIMP CBolbData :: GetArray (SAFEARRAY ** pData) {AFX_MANAGE_STATE (AfxGetStaticModuleState ()) // create object to send to server CSimpleObj * pMyOb = new CSimpleObj (); // set the string data pMyOb-> SetString ( "A SAFEARRAY from the server!"); // create blob to serialize object CBlob blob; // load the object into The blob * pdata = blob.load (PMYOB); // delete the PMYOB POINTER DELETE PMYOB; RETURN S_OK;} Finally, we do a dialog application with 2 buttons, 2 buttons response methods are: Void CClientdlg :: Onok () {// Create Com Smart Pointer from CLSID STRING TRY {IbolbDataPtr Pi ("