Pass C ++ objects in ATL DLL

xiaoxiao2021-03-06  38

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 ("

转载请注明原文地址:https://www.9cbs.com/read-64370.html

New Post(0)