每个主线程启动时,由于引用了ComServ,会执行下面一段代码,它会做COM的初始化:
begin
  OleAutHandle := SafeLoadLibrary('OLEAUT32.DLL');
  ComServer := TComServer.Create;
  if not ModuleIsLib then
  begin
    SaveInitProc := InitProc;
    InitProc := @InitComServer;
    AddTerminateProc(@AutomationTerminateProc);
  end;
end;
是不是每个线程启动后,也要执行一下这段代码?

解决方案 »

  1.   

    我试试看,不过我不太明白上面过程的含义;
    我用Synchronize()来执行,就可以了,为什么?请继续指点!
      

  2.   

    因为要调用COM前,必须调用CoInitializeEx来初始化COM。由于Delphi已经做了很好的封装,所以我们通常都没有感觉到。
    你是在线程中,所以这个初始化Delphi自然不会做,这个要你自己做了。刚才我查了一下,CoInitializeEx是在ComObj这个单元中执行的。
    另外,我想初始化不必用Synchronize来执行。
      

  3.   

    我想是的,COM需要初始化环境才可以,我看看COINITIALIZEEX怎么用。
    不过我觉得很有意思的是我用SYNCHRONIZE来执行就可正常运行,呵呵。
    如果有可能,能否告知怎么用COINITIALIZEEX()?
      

  4.   

    看MSDN或者Delphi的源码,我也没有使用过这个函数。
      

  5.   

    在OLEVARIANT前加一句 
    comobj.CoInitializeEx(nil,0);
    就可以生成COM了,但不理解,请指点!
      

  6.   

    这是MSDN的文档,上面是这么说的:
    CoInitializeEx
    Initializes the COM library for use by the calling thread, sets the thread's concurrency model, and creates a new apartment for the thread if one is required. HRESULT CoInitializeEx(void * pvReserved, //ReservedDWORD dwCoInit //COINIT value); Parameters 
    pvReserved 
    [in] Reserved; must be NULL. dwCoInit [in] Flags specifying the concurrency model and initialization options for the thread. Values for this parameter are taken from the COINIT enumeration. Any combination of values from the COINIT enumeration can be used, except that the COINIT_APARTMENTTHREADED and COINIT_MULTITHREADED flags cannot both be set. Return Values 
    This function supports the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following: 
    S_OK The COM library was initialized successfully on the calling thread. S_FALSE The COM library is already initialized on the calling thread. RPC_E_CHANGED_MODE A previous call to CoInitializeEx specified a different concurrency model for the calling thread. If running Windows 2000, this could also mean that a change from neutral threaded apartment to single threaded apartment occurred. Res 
    A thread must call CoInitializeEx or CoInitialize before calling any other COM library function except CoGetMalloc function and other memory allocation calls (CoTaskMemAlloc, CoTaskMemFree, CoTaskMemReAlloc, and the IMalloc methods on the task allocation supplied by CoGetMalloc). 
    Once the concurrency model for a thread is set, it cannot be changed. A call to CoInitializeEx on a thread that was previously initialized with a different concurrency model will fail and return RPC_E_CHANGED_MODE. CoInitializeEx must be called at least once, and is usually called only once, for each thread that uses the COM library. Multiple calls to CoInitializeEx by the same thread are allowed as long as they pass the same concurrency flag, but subsequent valid calls return S_FALSE. To close the COM library gracefully on a thread, each successful call to CoInitialize or CoInitializeEx, including any call that returns S_FALSE, must be balanced by a corresponding call to CoUninitialize. If neither concurrency model is specified by the dwCoInit parameter, the default is COINIT_MULTITHREADED. Objects created in a single-threaded apartment (STA) receive method calls only from their apartment's thread, so calls are serialized and arrive only at message-queue boundaries (when the Win32 function PeekMessage or SendMessage is called). Objects created on a COM thread in a multithread apartment (MTA) must be able to receive method calls from other threads at any time. You would typically implement some form of concurrency control in a multithreaded object's code using Win32 synchronization primitives such as critical sections, semaphores, or mutexes to protect the object's data. CoInitializeEx provides the same functionality as CoInitialize and also provides a parameter to explicitly specify the thread's concurrency model. The current implementation of CoInitialize calls CoInitializeEx and specifies the concurrency model as single-thread apartment. Applications developed today should call CoInitializeEx rather than CoInitialize. Because OLE technologies are not thread-safe, the OleInitialize function calls CoInitializeEx with the COINIT_APARTMENTTHREADED flag. As a result, an apartment that is initialized for multithreaded object concurrency cannot use the features enabled by OleInitialize. Because there is no way to control the order in which in-process servers are loaded or unloaded, it is not safe to call CoInitialize, CoInitializeEx, or CoUninitialize from the DllMain function. Requirements   Windows NT/2000/XP: Requires Windows NT 4.0 or later.
      Windows 95/98: Requires Windows 98 (or Windows 95 with DCOM).
      Header: Declared in objbase.h.
      Library: Use ole32.lib.See AlsoCOINIT, CoInitialize, Processes, Apartments, and Threads 
      

  7.   

    我已经很有收获了,谢谢chechy(我爱洁洁),已经给分。