I recently used the knowledge of COM components. I looked at the COM programming guide and thought it was good. I recorded my learning experience. This is a demo I wrote based on the tutorial.
Stopwatch interface implementation, Interface part my project is a dynamic library, the main source code is as follows:
Complete demo see http://download.csdn.net/detail/davidsu33/7750101
Stopwatch. h
# Pragma once # include <windows. h> # include <mmsystem. h> # include <unknwn. h> # include <WINBASE. h> # include "timer_ I .h" class stopwatcher {public: stopwatcher (void );~ Stopwatcher (void) ;}; class istopwatch: Public iunknown {public: // virtual unsigned long _ stdcall release () = 0; virtual hresult _ stdcall start () = 0; virtual hresult _ stdcall elaspedtime (float * elaspedtime) = 0 ;}; class cstopwatch: Public istopwatch {public: cstopwatch () {m_nrefvalue = 0; m_nfreq.quadpart = 0; queryperformancefrequency (& m_nfreq); addref ();} public: // virtual unsigned long _ stdcall release ()//{ // Delete this; // return 0; //}; // create the corresponding interface object virtual hresult stdmethodcalltype QueryInterface (/* [in] */refiid riid, /* [iid_is] [out] */_ RPC _ deref_out void _ rpc_far * ppvobject) {If (riid = iid_istopwatch) {* ppvobject = static_cast <istopwatch *> (this); Return s_ OK;} else if (riid = iid_iunknown) {* ppvobject = static_cast <iunknown *> (this ); return s_ OK;} * ppvobject = NULL; return e_nointerface ;};/ /Add reference virtual ulong stdmethodcalltype F (void) {interlockedincrement (& m_nrefvalue); Return m_nrefvalue ;}; // unreference virtual ulong inclurelease (void) {interlockeddecrement (& m_nrefvalue ); if (m_nrefvalue = 0) delete this; return m_nrefvalue ;}; virtual hresult _ stdcall start () {bool Bok = queryperformancecounter (& m_nstarttime); If (! Bok) return s_false; return s_ OK;}; virtual hresult _ stdcall elaspedtime (float * elaspedtime) {large_integer nstoptime; bool Bok = queryperformancecounter (& nstoptime); If (! Bok) return s_false; * elaspedtime = (float) (nstoptime. quadpart-m_nstarttime.quadpart)/m_nfreq.quadpart; return s_ OK;}; private: large_integer m_nfreq; large_integer m_nstarttime; volatile unsigned long m_nrefvalue ;}; // return istopwatch interface objectextern "C" hresult _ stdcall dllgetclassobject (refclsid rcsid, refiid RID, lpvoid * lpvoid) {If (rcsid = clsid_cstopwatch) {* lpvoid = static_cast <istopwatch *> (New cstopwatch); Return s_ OK;} * lpvoid = NULL; return class_e_classnotavailable ;}
Client call code
# Include ".. /stopwatch/stopwatcher. H "# include ".. /stopwatch/timer_ I .h "# include <iostream> # include <cstring> # include <cassert> # define timerdll l ".. /debug/stopwatch. DLL "# define procname" dllgetclassobject "typedef hresult (_ stdcall * getobjfunc) (refclsid, refiid, lpvoid *); Using namespace STD; void trace (const char * Str) {cout <STR <Endl;} void trace (const string & S) {cout <S. c_str () <Endl;} hresult creat Einstance (void ** P, hmodule * rhmod) {hmodule hmod = loadlibrary (timerdll); If (! Hmod) return e_fail; getobjfunc proc = (getobjfunc) getprocaddress (hmod, procname); If (! Proc) return e_fail; * P = proc; * rhmod = hmod; return s_ OK;} void freeinstance (hmodule hmod) {assert (freelibrary (hmod);} void testinstance () {void * fptr = NULL; hmodule hmod = NULL; hresult hR = createinstance (& fptr, & hmod); If (failed (HR) {trace ("createinstace failed "); return;} getobjfunc proc = (getobjfunc) (fptr); iunknown * PTR = NULL; // first obtain the class instance // then obtain the iunknown based on the class instance // finally obtain the interface object of its subclass through the iunknown QueryInterface Subclass interface object hR = proc (clsid_cstopwatch, iid_iunknown, (lpvoid *) & PTR); If (failed (HR) {trace ("GetObject failed"); return ;} if (! PTR) {trace ("PTR is null"); return;} istopwatch * ptrsw = NULL; HR = PTR-> QueryInterface (iid_istopwatch, (void **) & ptrsw ); assert (succeeded (HR); HR = ptrsw-> Start (); Assert (succeeded (HR); int m = 0; For (INT I = 0; I <10000000; ++ I) ++ m; float elaspedtime = 0; HR = ptrsw-> elaspedtime (& elaspedtime); Assert (succeeded (HR )); cout <"elaspedtime:" <elaspedtime <Endl; // release the object itself ptrsw-> release (); freeinstance (hmod);} int main (INT argc, char * argv []) {testinstance (); getchar (); Return 0 ;}