12.1.10Use ATL to create out-of-process Components
1. Problem Description
All components created earlier belong to In-process components, that is, the component object is in the same process as the customer process, and the customer process calls the services provided by the component object within the same process; external components, the component object and the customer process belong to different processes. The customer process can call the services provided by the component object across processes. How to create an external component?
2. Implementation skills
Use the ATL Create component Wizard to create an out-of-process component. First Use atl com Appwizard to create a project, as shown in 12-11.
Click OK to select the type used by the component to provide the service. Because it is an out-of-process component, select the executable type, as shown in 12-12.
|
(Click to view the big picture) Figure 12-11 create a project |
|
(Click to view the larger image) Figure 12-12 select the server type provided by the component |
Finally, add the interface provided by the component, which is basically the same as the interface described above.
3. InstanceCode
In this example, the simple model of consumers and producers is implemented by COM.
To create a component server, follow these steps.
(1) Use atl com appwzard to create a new project named procout.
(2)select the instance (.dllor .exe) used for the service ).
(3) Insert an object into the project. On the classview option page, right-click the project name, select new ATL object from the shortcut menu, and select simple object in the displayed dialog box, as shown in 12-13.
|
Figure 12-13 create a Component Object |
(4) Click Next. In the displayed dialog box, enter modu. For others, follow the default settings, as shown in 12-14.
|
Figure 12-14 component name |
(5) define interface functions. Right-click the interface imodu and choose add method from the shortcut menu. The "add production function" dialog box is displayed. Add the interface function hresult, parameter produce ([in] Long nproduce), as shown in 12-15.
|
Figure 12-15 Add a Production Function |
(6) Add the consumption function hresult customer ([in] Long nproduce), as shown in 12-16.
|
Figure 12-16 Add a Consumption Function |
(7) Add a property. On the classview page, right-click the interface and select the Add property command. The displayed dialog box is 12-17.
|
Figure 12-17 Add a property |
(8) Code of the component service. The component service provides two functions: Production and Consumption functions and attributes change. The Code is as follows.
Add member variables to the header file object. H of the cobject class:
Int m_lnum; // indicates the current quantity.
The reference code for the production function is as follows:
Stdmethodimp cobject: produce (long nproduce) { M_lnum + = nproduce; Return s_ OK; } |
The reference code of the consumption function is as follows:
Stdmethodimp cobject: customer (long ncustomer) { M_lnum-= ncustomer; If (m_lnum <0) { MessageBox (null, "no consumption", "prompt", mb_ OK ); M_lnum = 0; } Return s_ OK; } |
The reference code for interface property functions is as follows:
Stdmethodimp cobject: get_currentnum (long * pval) { * Pval = m_lnum; Return s_ OK; } Stdmethodimp cobject: put_currentnum (long newval) { M_lnum = newval; Return s_ OK; } |
(9) create a project procouttest Based on the dialog box on the client, and place two text boxes to indicate the number of production or consumption and the current number. Place two buttons to respond to production and consumption events. The reference code is as follows.
Add afxoleinit () to initinstance of procouttest to initialize the applicationProgramCom environment.
Introduce the procout. TLB library in stdafx. h:
# Import "procout. TLB" no_namespace |
Declare the smart pointer of the interface in procouttestdlg. h:
Add the code for creating an interface instance in oinitdialog in procouttest. cpp:
Hresult hR = m_iobject.createinstance (L "procout. Object "); If (failed (HR )) { MessageBox ("An error occurred while creating the interface instance! "); Return false; } M_iobject-> put_currentnum (100); // The number of initialization tasks is 100. M_iobject-> get_currentnum (& m_cur ); |
Code that responds to the production and consumption button events:
Void cprocouttestdlg: onproducebtn () { Updatedata (true ); M_iobject-> produce (m_num ); M_iobject-> get_currentnum (& m_cur ); Updatedata (false ); } Void cprocouttestdlg: oncustomerbtn () { Updatedata (true ); M_iobject-> customer (m_num ); M_iobject-> get_currentnum (& m_cur ); Updatedata (false ); } |
The running effect is 12-18.