COM object createdAnd then how to call the COM component. Here is the method for calling the COM Object in C ++.
There are generally three methods to create a COM object. You can create an object normally and use the cocreateinstance function. If you create an object in a remote system, use the cocreateinstanceex function. The cogetclassobject function is used to create multiple objects with the same clsid.
1. Use the cocreateinstance function to create a COM object.
// Load the generated file and the c file. # Include "atlproject1_ I .h" # include "atlproject1_ I .c" int _ tmain (INT argc, _ tchar * argv []) {// declare the interface pointer itrycom * It = NULL; // declare an hresult variable hresult hr; // initialize COM and notify windows to create the COM Object hR = coinitialize (0) in a single thread mode ); // use the succeded macro to determine whether the initialization is successful. If (succeeded (HR) {// load the COM Object hR = cocreateinstance (clsid_trycom, null, clsctx_inproc_server, iid_itrycom, (void **) & it ); // check whether the load is successful if (succeeded (HR) {long returnvalue; printf ("find dll \ n"); int A = 1; int B = 2; it-> Add (a, B, & returnvalue); printf ("% d", returnvalue); // For COM objects, after use, you must use release to release it-> release ();} // close the com library of the current thread, Uninstall all DLL files, and release resources. Couninitialize ();} system ("pause"); Return 0 ;}
Here are two important functions: cocreateinstance and couninitialize.
For the couninitialize () function, couninitialize closes the com library of the current thread, unmounts all DLL loaded by the thread, releases any other resources, and closes the thread to maintain all RPC connections.
After a thread calls coinitialize for COM Initialization, The coinitialize function is called to release the com library before the program is completely closed.
Then there is the cocreateinstance function, and its prototype is:
Stdapi cocreateinstance (refclsid rclsid, // Class Identifier (CLSID) of the created COM Object lpunknown punkouter, // pointer to interface iunknown, indicating whether to aggregate DWORD dwclscontext, // context refiid riid for running executable code, // The interface identifier of the created COM Object lpvoid * NPV // used to receive pointer variables pointing to the COM object interface address );
Rclsid
[In] is the CLSID (128 bits) used to uniquely identify an object. You need to use it to create a specified object. This value is generally stored in the xxx_ I .c file generated by com. You can include this file directly or add the CLSID in this document to use it directly as a global constant.
Punkouter
[In] if it is null, this object is not part of an aggregate object. If it is not null, the Pointer Points to the iunknown interface of an aggregate object.
Dwclscontext
[In] component category. pre-defined values can be used in the clsctx enumerator. Optional values are as follows:
Clsctx_inproc_server creates components that run in the same process. To be able to run in the same process, the component must be implemented in the DLL.
Clsctx_inproc_handler creates a processor in the process. A processor in a process is actually a component in a process that only implements a part of the component. Other components of this component will be implemented by a non-process component on the local or remote server.
Clsctx_local_server creates a component that runs in another process on the same machine. The local server is implemented by exe.
Clsctx_remote_server creates a component that runs on a remote machine. This flag requires the Distributed COM to work properly.
Riid
[In] refers to the interface identifier, which is used to communicate with objects. It also exists in xxx_ I .c.
BPPV
[Out] is used to receive pointer variables pointing to the interface address. If the function is successfully called, * the bpsvincludes the requested interface pointer. Return Value:
S_ OK: the specified COM object instance is successfully created.
Regdb_e_classnoregulatory: the specified class is not registered in the registry. It may be that the specified dwclscontext is not registered or the server type in the registry is damaged.
Class_e_noaggregation: This class cannot be created as an aggregate type.
E_nointerface: the specified class does not implement the request interface, or the iunknown interface does not expose the request interface.
However, this function is actually implemented by calling the cogetclassobject function:
CoGetClassObject(rclsid,NULL ,dwClsContext, IID_IClassFactory, &pCF);hresult = pCF->CreateInstance(pUnkOuter, riid, ppv);pCF->Release();
2. Use cogetclassobject to create a COM object.
Cogetclassobject does not directly create COM components, but creates a factory class, and then creates a COM object for the factory object class. The interface of the factory class is iclassfactory. The last parameter of the cocreatinstance function points to a factory object, and the last parameter of cogetclassobject points to a final COM object.
The cogetclassobject function is very similar to cocreateinstance. There is only one parameter. cocreatinstance receives an iunknown pointer while cogetclassobject receives a coserverinfo pointer. The prototype is as follows:
Stdapi cogetclassobject (refclsid rclsid, // is the ID of the COM Object Class, same as DWORD dwclscontext, // executable code context, same as coserverinfo * pserverinfo, // server message, if it is not created remotely, it is generally set to null, with a different refiid riid, // here is the interface ID of the factory class, generally set to iid_iclassfactorylpvoid * bp ); // This is the record's factory object pointer
After you have a factory, call the createinstance function of the factory to create a COM object. Prototype:
Hresult stdmethodcalltype createinstance (iunknown * punkouter, // pointer to the iunknown interface, indicating whether to aggregate, generally set to null not to aggregate refiid riid, // The ID of the COM peer interface void ** ppvobject); // The returned COM Object Pointer
A simple example is as follows:
// Load the generated file and the c file. # Include "atlproject1_ I .h" # include "atlproject1_ I .c" int _ tmain (INT argc, _ tchar * argv []) {// declare the interface pointer itrycom * It = NULL; // iclassfactory * IFP = NULL; // declare an hresult variable hresult hr; // initialize COM, and tells windows to create the COM Object hR = coinitialize (0) in a single thread mode; // use the succeded macro to determine whether the initialization is successful. If (succeeded (HR) {// load factory class hR = cogetclassobject (clsid_trycom, clsctx_inproc_server, null, iid_iclassfactory, (void **) & IFP ); // check whether the load is successful if (succeeded (HR) {hR = IFP-> createinstance (null, iid_itrycom, (void **) & it ); // use the factory to create a COM Object IFP-> release (); // release if (succeeded (HR) {long returnvalue; printf ("find dll \ n "); int A = 1; int B = 2; it-> Add (a, B, & returnvalue); printf ("% d", returnvalue); // For COM objects, after use, you must use release to release it-> release (); // Release} // close the com library of the current thread, Uninstall all DLL files, and release resources. Couninitialize ();} system ("pause"); Return 0 ;}
3. ignore the remote instance creation function ex. Finally, consider not using cocreateinstance or cogetclassobject and directly obtain dllgetclassobject from the DLL, then generate the Class Object and class instance (this method is suitable for you to use a component, but you do not want to register the component in the registry ). The previous two functions can be called because they have registered the DLL for their unique ID through the registry in the system. Therefore, these two functions are called, obtain the corresponding DLL from the system. Finally, it is a method that does not register DLL. The implementation is as follows:
// Load the generated file and the c file. # Include "atlproject1_ I .h" # include "atlproject1_ I .c" int _ tmain (INT argc, _ tchar * argv []) {// define such a function pointer typedef hresult (_ stdcall * pfngco) (refclsid, refiid, void **); // declare a function pointer pfngco fngco = NULL; // load dllhinstance hdllinst = loadlibrary ("D:/360 data/important data/My Documents/Visual Studio 2012/projects/trydll/atlproject1.dll "); // find the dllgetclassobject function in the DLL and assign it to the fngco pointer. The fngco pointer can be used to create a factory class fngco = (pfngco) getp Rocaddress (hdllinst, "dllgetclassobject"); If (fngco! = 0) {// factory object iclassfactory * PCF = NULL; // release the fngco function, that is, the dllgetclassobject function, to obtain a factory class object, then, hresult hR = (fngco) (clsid_trycom, iid_iclassfactory, (void **) & PCF); If (succeeded (HR) & (PCF! = NULL) {itrycom * Itry = NULL; HR = PCF-> createinstance (null, iid_itrycom, (void **) & Itry); If (succeeded (HR) & (Itry! = NULL) {long returnvalue; printf ("find dll \ n"); int A = 1; int B = 2; Itry-> Add (A, B, & returnvalue); printf ("% d", returnvalue); Itry-> release () ;}pcf-> release ();}} // release the loaded dllfreelibrary (hdllinst); System ("pause"); Return 0 ;}
ATL calls COM Object