DOCUMENT:Q280803 01-JUL-2002 [visualc] TITLE :PRB: CoCreateInstance Stops and Creates Many ATL Objects PRODUCT :Microsoft C Compiler PROD/VER::3.0,6.0 OPER/SYS: KEYWORDS:kbATL ====================================================================== ------------------------------------------------------------------------------- The information in this article applies to: - The Microsoft Active Template Library (ATL) 3.0 - Microsoft Visual C++, 32-bit Editions, version 6.0 - The Microsoft Foundation Classes (MFC) ------------------------------------------------------------------------------- SYMPTOMS ======== In Visual C++: If you call CoCreateInstance on a large number of Active Template Library (ATL) objects (for example, about 100, although this number varies), the call may not succeed and may return an HRESULT of 0x80040154 (REGDB_E_CLASSNOTREG). In Visual Basic: This behavior can also occur with CreateObject because it is a wrapper for CoCreateInstance. If you call CreateObject from Microsoft Visual Basic, from Microsoft Visual Basic for Applications (VBA), or from Visual Basic Script on a large number of Active Template Library (ATL) objects, the call may not succeed. For example, in Visual Basic Script, you may receive the following error message: Microsoft VBScript runtime error: ActiveX component can't create object: 'Class67.Object67' CAUSE ===== MFC Libraries: This problem can also occur if the MFC libraries are statically linked to the associated DLLs, because the MFC libraries use TLS slots. CRT Libraries: This problem can occur if the objects contain a large number of ATL DLL files, and if the C run-time libraries (CRT) are linked statically. The default setting for any build of ATL DLL is to be statically linked. NOTE: Most of the CRT is linked when _ATL_MIN_CRT is not defined. The CRT library uses thread-local storage (TLS). Each time that a statically-linked CRT-dependent DLL is mapped into a process, the CRT is initialized, during which a TLS slot is allocated. There are only TLS_MINIMUM_AVAILABLE slots available for each process. This constant is guaranteed to be at least 64 slots on all Win32 platforms. For additional information about this limitation in TLS slots, click the article number below to view the article in the Microsoft Knowledge Base: Q193462 PRB: A Process Can Map 64 (or Less) Statically-linked CRT DLLs RESOLUTION ========== Make sure that the ATL DLLs link dynamically with the CRT libraries or with the MFC libraries. When you link dynamically with the CRT and MFC, you can benefit from the following: - Faster DLL load times - Better memory usage - Improved speed CRT Libraries: To link the ATL DLLs dynamically with the CRT libraries, follow these steps: 1. In Project Settings for the build in question, click the C/C++ tab, and then set the Category to Code Generation. 2. In the Use run-time library list, change the setting as follows: a. For Release builds, change Multithreaded to Multithreaded DLL. b. For Debug builds, change Debug Multithreaded to Debug Multithreaded DLL. MFC Libraries: To link the ATL DLLs dynamically with the MFC libraries, follow these steps: 1. In Project Settings for the build in question, click the General tab. 2. On the General tab, in the Microsoft Foundation Classes list, change "Use MFC in a Static Library" to "Use MFC in a Shared DLL". STATUS ====== This behavior is by design. MORE INFORMATION ================ Steps to Reproduce the Behavior ------------------------------- 1. Create a large number of ATL DLL projects that are named Class"X" (without the quotation marks), where X is a number between 1 and 100 for computers that are running on one of the following operating systems: - Windows NT - Windows Millennium Edition - Windows 98 - Windows 95 2. Insert an ATL simple object named ObjectX into each DLL project. 3. Build each project. 4. Paste the following code into a file that has an extension of .vbs, for example, TestTls.vbs: FOR i = 1 TO 100 ProgId = "Class" & CSTR(i) & "." & "ObjectX" WScript.Echo "Creating component " & CSTR(i) SET Obj = CreateObject(ProgId) SET Obj = NOTHING NEXT 5. Run the TestTls.vbs file: at the command prompt, type the following (CScript.exe must be in the PATH environment variable): CScript TestTls.vbs The exact output that you receive will vary depending on the version of the OS. The following is an example of the output produced on one computer: .... Creating component 65 Creating component 66 Creating component 67 TestTLS.VBS(4, 2) Microsoft VBScript runtime error: ActiveX component can't create object: 'Class67.ObjectX' Additional query words: ====================================================================== Keywords : kbATL Technology : kbVCsearch kbAudDeveloper kbMFC kbATLsearch kbATL300 kbVC600 kbVC32bitSearch Version : :3.0,6.0 Issue type : kbprb ============================================================================= THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. Copyright Microsoft Corporation 2002.