Microsoft KB Archive/235718

= INFO: FTM Aggregated Objects Cannot Hold Proxies =

Article ID: 235718

Article Last Modified on 2/12/2007

-

APPLIES TO


 * Microsoft Windows 2000 Standard Edition
 * Microsoft Windows NT 4.0
 * Microsoft Windows 95
 * Microsoft Windows 98 Standard Edition

-



This article was previously published under Q235718



SUMMARY
An object that aggregates with the Free Threaded Marshaler (FTM) cannot hold references to proxies of other Component Object Model (COM) objects. Proxies are apartment sensitive. When you access proxies from a different apartment, they return the RPC_E_WRONG_THREAD error.

You can store the interface in either a stream or a Global Interface Table (GIT) cookie. This reconstitutes the interface according to the method that is used to serialize it. To do this, register the interface pointers with GIT, and hold the GIT cookies in place of proxies. You can also use either the CoMarshalInterface function or the CoMarshalInterThreadInterfaceInStream function to keep the proxy in a marshaled stream.



MORE INFORMATION
Although the FTM can eliminate the overhead of a proxy and stub, it can also cause the object to simulate a neutral apartment. Use care when objects that use FTM have interface pointers as data members.

Consider the following example, in which an object holds an interface pointer as a data member:

Class First:public IFirst {  LONG m_cRef; ISecond* m_pSec; First:m_cRef(0) {     HRESULT hr = CoCreateInstance(CLSID_Second,0,                  CLSCTX_INPROC,IID_ISecond,(void**)&m_pSec); assert(SUCCEEDED(hr)); }  :   :   :

}  If First is an in-process class and is marked ThreadingModel = "Both," you can only access the m_pSec data member from an apartment that runs the CoCreateInstance function. This is because the constructor of First always executes in an apartment of the thread that calls CoCreateInstance.

If a method called Method1 in First uses the interface pointer data member m_pSec, and the First object uses FTM, you can invoke this method from other apartments. This causes a problem because m_pSec is not valid in other apartments.

In fact, if you create the Second object in a different apartment because of ThreadingModel incompatibilities, the First object holds pointers to proxies. When you access these proxies from the wrong apartment, they return the RPC_E_WRONG_THREAD error.

As a result, FTM objects must never hold onto direct interface pointers to other objects or proxies. Instead, FTM objects must use the marshaled form of interface pointers; that is, DWORD cookies in the Global Interface Table or marshaled stream with the marshaling application programming interface (API). The GIT holds interface pointers and returns apartment-independent interface pointer identifiers (GIT cookies). To use the GIT, call CoCreateInstance with CLSID_StdGlobalInterfaceTable.

NOTE: You can implement the Global Interface Table from Windows NT 4.0 Service Pack 3 or later, or from Windows 95 with DCOM 95 1.0 or later. The Global Interface Table is included with Windows 98 and Windows 2000.

