PRB: CoCreateInstance Fails in RPC Server

ID: Q141264

4.00    | 3.51
WINDOWS | WINDOWS NT kbole kbprg kbprb

The information in this article applies to:

SYMPTOMS

In a RPC server application, calls to any OLE APIs that cause an interface to be marshalled will fail if the application has already called RpcServerListen. In particular, CoGetClassObject and CoCreateInstance fail with E_OUTOFMEMORY even though CoInitialize succeeded and the object is registered correctly.

NOTE: This problem has been fixed in Windows NT 4.0. CoGetClassObject and CoCreateInstance will no long fail if the application has called RpcServerListen or RpcMgmtWaitServerListen.

CAUSE

OLE is also acting as a RPC server. If the application calls RpcServerListen or RpcMgmtWaitServerListen before OLE calls RpcServerListen, OLE's call to RpcServerListen will return RPC_S_ALREADY_LISTENING. This is correct behavior in a RPC server application because RPC allows only a single thread to block waiting for RPC client requests. Unfortunately, OLE treats this return value as an error rather than success.

RESOLUTION

To instantiate and use COM objects in an RPC server application, you need to force OLE to call RpcServerListen first. The application should then expect its own call to RpcServerListen to return RPC_S_ALREADY_LISTENING, which should be treated as success.

Simply calling CoInitialize or OleInitialize is not sufficient to get OLE to call RpcServerListen. OLE calls RpcServerListen the first time it marshals an interface. Therefore, the application must marshal an interface before calling RpcServerListen. This can be done by calling APIs such as CoRegisterClassObject or CoMarshalInterface. For example, after calling CoInitialize, the application can register a dummy class factory with CoRegisterClassObject and then immediately revoke it with CoRevokeClassObject.

STATUS

This behavior is by design.

MORE INFORMATION

An RPC server application receives RPC calls via the RPC libraries, which create a pool of threads for dispatching RPC calls within the server application. An incoming call is assigned to a thread from the pool, which unmarshals the parameters and calls the appropriate RPC interface method in the server. This allows multiple RPC calls to be serviced simultaneously.

Because the RPC server application has no control over which thread is used for any given call, the RPC server must be aware of and follow the rules of the Apartment Model of OLE threading supported by Windows 95 and Windows NT (beginning with version 3.51) if it will also be acting as a COM client. In some simple cases, you may just need to use a sequence of CoInitialize, CoCreateInstance, use and release the object, and CoUninitialize all within an individual RPC method call. Other cases may require using separate threads with message loops (apartments) to own the objects and marshaling of interfaces between threads.

For more information on the Apartment Model, look up "Processes and Threads" in the OLE Programmer's Reference included with the Win32 SDK online documentation, or see the OLE Release Notes included with the Win32 SDK for Windows 95 and Windows NT 3.51 (Mstools\Samples\Ole\Olerel.wri).

Additional reference words: 2.0 2.00 4.00 KBCategory: kbole kbprg kbprb KBSubcategory: LeTwoCom

Keywords          : LeTwoCom 
Version           : 4.00    | 3.51
Platform          : NT WINDOWS

Last Reviewed: July 26, 1996