Problem:Differences between calling COM and calling DLL
The DLL call must be as follows:
Hmodule hdll =: loadlibrary (".. // debug // wdll. dll ");
If (hdll = NULL)
{
MessageBox ("failed to load dynamic link library", "warning", mb_ OK | mb_iconwarning );
Return;
}
Typedef int (* yadd) (INT, INT );
Yadd = (yadd): getprocaddress (hdll, "add ");
You can call com as follows:
# Import "../debug/COM. dll"
Afxoleinit ();
Ikeycomptr keycom;
Hresult hR = keycom. createinstance ("devicecom. keymgr ");
If (failed (HR ))....
Are the calling methods of these two DLL types fixed ?? Are there any connections or unified methods? When to use com and traditional DLL?
Reply:
Do not associate DLL with COM, or regard com as a DLL. dll is only used to load COM, but COM does not necessarily use dll as the carrier, or EXE or others, as for calling methods, this is defined by specification. First, let's look at the basic knowledge of COM.
Reply:
By the way, their calling methods are basically fixed.
But you need to distinguish between COM and DLL.
Reply:
Can two types of DLL be called using traditional call methods? No? Why?
Reply:
Com can achieve interoperability, not DLL
Reply:
> Can two types of DLL be called using traditional call methods? No? Why?
No! Traditional calling is through functions;
The COM component is called through the interface. This interface can be used only when the interface pointer is obtained through createinstance. all calls are implemented through the interface.
Reply:
Com is a better DLL, so com can be implemented through the traditional DLL call method.
COM has a global export function.
Dllgetclassobject.
The com library is also used when the COM component is loaded.
Loadlibrary
Getprocaddress ("dllgetclassobject ")
.
Com only registers the dll path and other information into the registry.
Reply:
Let's see how the following com library helps us run the COM object.
Iunknown * punk = NULL;
Iobject * pobject = NULL;
Coinitialize (null );
Cocreateinstance (clsid_object, clsctx_inproc_server, null, iid_iunknown, (void **) & punk );
Punk-> QueryInterface (iid_iojbect, (void **) & pobject );
Punk-> release ();
Pobject-> func ();
Pobject-> release ();
Couninitialize ();
This is a typical framework for creating COM components, but I am interested in cocreateinstance. Let's take a look at what it has done internally. The following is a pseudo code implemented internally:
Cocreateinstance (....)
{
.......
Iclassfactory * pclassfactory = NULL;
Cogetclassobject (clsid_object, clsctx_inproc_server, null, iid_iclassfactory, (void **) & pclassfactory );
Pclassfactory-> createinstance (null, iid_iunknown, (void **) & punk );
Pclassfactory-> release ();
........
}
In this section, the class factory object is obtained first, and then the class factory creates components to obtain the iunknown pointer. Take a further step and check the internal pseudo code of cogetclassobject:
Cogetclassobject (.....)
{
// Query the Registry clsid_object to find the location and file name of the component DLL.
// Load the dll library
Loadlibrary
// Use the getprocaddress ("dllgetclassobject") function to obtain the function pointer of the dllgetclassobject function in the dll library.
// Call dllgetclassobject
}
What is dllgetclassobject? It is used to obtain the class factory object. Only the class factory can be used to create components.
The following is the pseudo code of dllgetclassobject:
Dllgetclassobject (...)
{
......
Cfactory * pfactory = new cfactory; // class factory object
Pfactory-> QueryInterface (iid_iclassfactory, (void **) & pclassfactory );
// Query the iclassfactory pointer
Pfactory-> release ();
......
}
The cogetclassobject process has reached this point. Now return cocreateinstance and check the pseudo code of createinstance:
Cfactory: createinstance (.....)
{
...........
Cobject * pobject = new cobject; // Component Object
Pobject-> QueryInterface (iid_iunknown, (void **) & punk );
Pobject-> release ();
...........
}
Therefore, we can not register COM components, but use the same process above to follow the call method of common dll:
The loadlibary and getprocaddress methods and the corresponding COM interface header files are added to the Lib file generated by com DLL to successfully call a com.
Reply:
Good, detailed enough. digest it slowly and close it :)
Reply:/**
* Dllgetclassobject function prototype Declaration
*/
Typedef int (callback * dllgetclassobjectptr) (refclsid, refiid, lpvoid *);
/**
* Returns an interface object from Com. If the interface is successful, true is returned. Otherwise, false is returned.
* @ Param lpdll [in]: dll path
* @ Param strrclsid [in]: Class Object string mnemonic
* @ Param strriid [in]: interface object string mnemonic
* @ Param GMM [out]: returned interface object
*/
Int _ stdcall getcominterface (maid, maid, maid)
{
/**
* Load DLL
*/
Hinstance = NULL;
Dllgetclassobjectptr procfunc = NULL;
Bool bsucces = false;
Hinstance = loadlibrary (lpdll );
If (hinstance)
{
/**
* Obtain the address of the dllgetclassobject function.
*/
Procfunc = (dllgetclassobjectptr) getprocaddress (hinstance, "dllgetclassobject ");
If (procfunc)
{
/**
* Get The GUID of the class and interface.
*/
CLSID rclsid;
IID riid;
Clsidfromstring (lpolestr) strrclsid, & rclsid );
If (strriid! = NULL)
{
Clsidfromstring (lpolestr) strriid, & riid );
}
Else
{
Riid = iid_iunknown;
}
/***
* Obtain the class factory and create an interface object
*/
Iclassfactory * PIF = NULL;
If (procfunc (rclsid, iid_iclassfactory, (void **) & PIF) = s_ OK)
{
Bsucces = (PIF-> createinstance (null, riid, GMM) = s_ OK );
PIF-> release ();
PIF = NULL;
}
}
/**
* If an excuse object fails to be created, release the DLL
*/
If (! Bsucces)
{
Freelibrary (hinstance );
}
}
Return bsucces;
}