276°
Posted 20 hours ago

Essential COM

£16.995£33.99Clearance
ZTS2023's avatar
Shared by
ZTS2023
Joined in 2023
82
63

About this deal

II faststringitf.cPPIII (part of DLL, not client) II #include "faststring.h" #include "faststringitf.h" FastStringltf::FastStringltf(const char *psz) m_pThis(new FastString(psz)) { assert(m_pThis != 0); } class IFastString { public: virtual void *Dynamic_Cast(const char *pszType) =0; virtual void Delete(void) = 0; virtual int Length(void) = 0; virtual int Find(const char *psz) 0; } ; bool SaveString(IFastString *pfs, const char *pszFN){ bool bResult = false; IPersistentObject *ppo = (IPersistentObject*) pfs->Dynamic_Cast("IPersistentObject"); if (ppo) bResult = ppo->Save(pszFN); return bResult; } The [1 oca1] attribute suppresses the generation of networking code for this interface. This attribute is necessary to relax COM's requirement that all remotable methods must return HRESULTs. As discussed in later chapters, IUnknown is treated specially when dealing with remote objects. Note that the actual IDL interface definitions found in the SDK headers will vary slightly from the definitions found in this text. The actual definitions often contain additional attributes to optimize the generated networking code that are not relevant to the discussion at hand. When in doubt, consult the latest version of the SDK header files for the complete definition. IUnknown is the root of all COM interfaces. IUnknown is the only COM interface that does not derive from another COM interface. Every other legal COM interface must derive from IUnknown directly or from one other legal COM interface, which itself must derive either from IUnknown directly or from one other legal COM interface. This means that at the binary level all COM interfaces are pointers to vtbls that begin with the three entries Que rylnte rface, AddRef, and Release. Any interface-specific methods will have vtbl entries that appear after these common three entries. To derive from an interface in IDL, either define the base interface in the same IDL file or use the import directive to make the external IDL definition of the base interface visible in the current scope: A client that wants to treat an object as a CatlDog simply uses Que rylnte rface to bind both types of pointers to the object. If one of the Querylnterface calls fails, then the object in question is not a Cat/Dog and the client can cope with this as it chooses. Because implementations can expose multiple interfaces, there is little loss of semantic or type information in prohibiting interfaces from having more than one base inheritance. COM supports a notation technique that expresses which interfaces are available from an object. This technique adheres to the COM philosophy of separation of interface from implementation and does not betray any implementation details of the object other than the list of interfaces it exposes.

Essential Communications Executive Coaching Los Angeles - Essential Communications

class PugCat : public lPug, public lCat { LONG m_cRef; protected: virtual -PugCat(void); public: PugCat(void); II lUnknown methods STDMETHODIMP Query1nterface(REFI1D riid, void **ppv); STDMETHODlMP_(ULONG) AddRef(void); STDMETHODlMP_(ULONG) Release(void); II lAnimal methods STDMETHODlMP Eat(void); II 1Dog methods STDMETHOD1MP Bark(void); class IExtensibleObject { public: virtual void *Dynamic_Cast(const char* pszType) =0; virtual void DuplicatePointer(void) = 0; virtual void DestroyPointer(void) = 0; }; define SUCCEEDED(hr) (long(hr) >= 0) #define FAILED(hr) (long(hr) < 0) These two macros take advantage of the fact that the severity bit is also the sign bit when treating an HRESULT as a signed integer. The SDK headers contain the definitions of all standard HRESULTs. These HRESULTs have symbolic names that correspond to the three components of an HRESULT using the following format: S_OK - successful normal operation S_FALSE - used to return logical false successfully E_FAIL - generic failure E_NOTIMPL - method not implemented E_UNEXPECTED - method called at incorrect time This technique works because the compiler has enough knowledge about the layout and type hierarchy of the implementation class to examine an object at runtime to determine whether it in fact derives from IPersistentObject. Therein lies the problem. RTTI is a very compiler-dependent feature. Again, the DWP mandates the syntax and semantics for RTTI, but each compiler vendor's implementation of RTTI is unique and proprietary. This effectively destroys the compiler independence that has been achieved by using abstract base classes as interfaces. This is unacceptable for a vendor-neutral component architecture. One very tractable solution to the problem is to leverage the semantics of dynami c_cast without using the actual compiler-dependent language feature. Exposing a well-known method explicitly from each interface that will perform the semantic equivalent of dynami c_cast can achieve the desired effect without requiring all entities to use the same C++ compiler:against the precise signature of the interface class, and any changes to the interface definition require that the client recompile to take advantage of the change. Worse yet, changing the interface definition completely violates the encapsulation of the object (its public interface has changed) and would break all existing clients. Even the most innocuous change, such as changing the semantics of a method while holding its signature constant, renders the installed client base useless. This implies that interfaces are immutable binary and semantic contracts that must never change. This immutability is required to have a stable, predictable runtime environment. Despite the immutability of interfaces, it is often necessary to expose additional functionality that may not have been anticipated when an interface was initially designed. It is tempting to take advantage of the knowledge of vtbllayout and simply append new methods to the end of an existing interface definition. Consider the initial version of IFastStri ng: severity>_ For example, the HRESULT STG_S_CONVERTED indicates that the facility code is FACILITY_STORAGE (which means that this result is related to Structured Storage or Persistence); the severity bit is SEVERITY_SUCCESS (which means that the call was able to perform the operation successfully) and that, in this case, the operation converted the underlying file to support structured storage. HRESULTs that are universal and are not tied to a particular technology use FACILITY_NULL and their symbolic name does not contain the facility code prefix. Some common FACILITY_NULL HRESULTs are

Essential COM - Don Box - Google Books

as the compiler and linker will initialize each vtbl to point to the single method implementation. This is a natural side effect of using multiple inheritance in C++. The following is a class definition that produces objects that support the IPug and lCat interfaces: class IPersistentObject : public IExtensibleObject { public: virtual bool Load(const char *pszFileName) 0; virtual bool Save(const char *pszFileName) 0; } ; shaped much of the mindset of the C++ community at large. One of the principal goals for C++ was to allow programmers to build user-defined types (UDTs) that could be reused outside their original implementation context. This principle underpins the idea of class libraries or frameworks as we know them today. Since the introduction of C++, a marketplace for C++ class libraries emerged, albeit rather slowly. One reason that this marketplace has not grown as fast as one might expect is related to the addition of new techniques for finding interfaces beyond the normal offset calculation used when simply casting to a base class. The source code that accompanies this book includes a header file, i nttabl e. h, that defines interface table entries as follows:

Changelog

Sub TryToSnoreAndlgnore(obj as Object) On Error Resume Next ' ignore errors Di m pug as lPug Set pug = obj • VM calls QueryInterface If Not (pug is Nothing) Then pug.Snore End if Dim cat as lCat Set cat = obj • VM calls QueryInterface If Not (cat is Nothing) Then cat.lgnoreMaster End if End Sub if (riid == IID_IUnknown) *ppv = static_cast (this); As was shown in the case of FastSt ri ng and IExtensi b1eObj ect from the previous chapter, this code will not compile because the cast is ambiguous and could be satisfied by using more than one base class. Instead, the implementation needs to select a more precise type to use in the cast: Figure 2.2 HRESULTs As shown in Figure 2.2, HRESULTs are partitioned into three bit-fields: the severity bit, the facility code, and the information code. The severity bit indicates whether the operation succeeded or not, the facility code indicates what technology the HRESULT corresponds to, and the information code is the precise result within the specified technology and severity. The SDK headers define two macros that simplify coding with .HRESULTs: Smart pointers seem very attractive at first glance but can be very dangerous as they lull the programmer into a dream-like state in which nothing COM-related seems to matter. Smart pointers do solve real problems, especially in the face of exceptions; however, when used carelessly, smart pointers can introduce as many defects as they prevent. For example, many smart pointers allow any interface method to be accessed via the smart pointer's operator ->. Unfortunately, this allows clients to call Release via the arrow operator without notifying the underlying smart pointer that its automatic Release call in its destructor is now redundant and not allowed. include "ifaststring.h" i nt f(voi d) { int n = -1; IFastString *pfs = CreateFastString("Hi Bob!"); if (pfs) { n = pfs->Find(" ob"); pfs->Delete(); }

Essential Education GED Academy™ | Essential Education

define END_INTERFACE_TABLE() \ { 0, 0, 0 } }; return table; } All that is required is a routine tha mats the resultant GUID into one of four formats suitable for inclusion in IDL or C++ source code. When working in IDL, the fourth format (the canonical text form) is what is needed. To associate the physical name of the interface with its definition in IDL, the second nonoptional interface attribute, [uui d], is used. The [uui d] attribute accepts one parameter, the canonical textual form of the GUID: IUnknown The COM interface IUnknown serves the same purpose as the IExtensi bl eObject interface defined in the previous chapter. The following is the final version of IExtensi bl eObject that appeared at the end of the chapter:If the object presented to this function is both lCat and lPug compatible, then both functionalities are exploited. If the object is not in fact lCat or lPug compatible, then this particular function simply ignores the missing aspect(s) of the object. The following is the semantically equivalent version using Que rylnte rface: void TryToSnoreAndlgnore(/* [in] *1 lUnknown *pUnk) { HRESULT hr; lPug ''(pPug = 0; hr = pUnk->Querylnterface(llD_lPug, (void**)&pPug); if (SUCCEEDED(hr)) {II the object is Pug-compatible pPug->Snore(); pPug->Release(); II R2 } pfs = CreateFastString("Feed BOB"); if (pfs) { ppo = (IPersistentObject *) pfs->Dynamic_Cast("IPersistentObject"); if (ppo) { ppo->Save("C:\\autoexec.bat"); ppo->DestroyPointer(); } With this type hierarchy in place, the client is able to query an object dynamically for a given interface using a compiler-independent construct: late to object layout. Because all member functions in COM interface definitions are pure virtual, the derived class must provide an implementation of every method that is present in any of its interfaces. Methods that are common to two or more interfaces (e.g., Querylnterface, AddRef, etc.) need to be implemented only once, 3 Which was highly inspired by a discussion between the author and Tye McQueen during a COM seminar.

Essentials for Men FW23 Collection | SSENSE UK Fear Of God Essentials for Men FW23 Collection | SSENSE UK

Because each pointer is now treated as an autonomous entity with respect to lifetime, the client does not need to be concerned with which pointer refers to which object. Instead, the client simply follows the two simple rules and allows the object to manage its own lifetime. If desired, the idiom of calling Dupl i catePoi nter and DestroyPo; nter cOllld easily be hidden behind a C++ smart pointer. Using this reference counting scheme allows an object to expose multiple interfaces in an extremely uniform manner. The capability to expose multiple interfaces from a single implementation class allows a data type to participate in a variety of contexts. For example, a new persistence subsystem could define its own custom interface for telling objects to load and save themselves to some customized storage medium. The FastStri ng class could add support for this functionality simply by deriving from the subsystem's persistence interface. Adding this support does not in any way affect the installed base of clients that may be using the prior persistence interface to save and load a string to disk. Having a mechanism for runtime interface negotiation can act as a cornerstone for building a dynamic system from components that can evolve over time.

Sewing Patterns, Sewing Machines & Haberdashery

Methods and Results Method results are one aspect of COM where the logical and physical worlds diverge. Virtually all COM methods physically return an error number of type HRESULT. The use of a uniform result type allows COM's remoting architecture to overload the result of a method and also indicate communications errors simply by reserving a range of values for RPC errors. HRESULTs are 32-bit integers that provide information to the caller's runtime environment about what type of error may have occurred (e.g., network errors, server failures). For many COM-compatible implementation languages (e.g., Visual Basic, Java), these HRESULTs are intercepted by a supporting runtime or virtual machine and mapped to programmatic exceptions. if (riid == IID_IUnknown) *ppv = static_cast (this); Either of these two code fragments is legal for the implementation of PugCat. The former version is preferred, as many compilers produce slightly more efficient code when the leftmost base class is used. 4 Que rylnte rface describes the "shape" of the second parameter's pointer type. This relationship can be enforced at compile time through the use of the following C preprocessor macro: #define llD_PPV-ARG(Type, Expr) llD_##Type, \ reinterpret_cast (static_cast (Expr)) Given this macro,3 the compiler will ensure that the expression used in the following call to Que rylnte rface is of the correct type and that the appropriate level of indirection is in use:

Asda Great Deal

Free UK shipping. 15 day free returns.
Community Updates
*So you can easily identify outgoing links on our site, we've marked them with an "*" symbol. Links on our site are monetised, but this never affects which deals get posted. Find more info in our FAQs and About Us page.
New Comment