描述:
我用ATL写了个最简单的com(MessageBoxSvr.dll),里面只有一个接口IMsg,接口只有一个方法(函数)SendMsg(),函数只有一条语句MessageBox("Hello Com");
我在客户调用是这样的,在stdafx.h中用#import "..."(MessageBox.dll的完整路径),然后再对话框初始化中调用OleInitialize();测试按钮调用我的com:
void CMessageClientDlg::OnButton1()
{
// TODO: Add your control notification handler code here
IMsgPtr pMsg = NULL;//智能指针
pMsg.CreateInstance(__uuidof(IMsg));
pMsg->SendMsg();
}
编译通过,执行的时候。出现错误
“Runtime Error,abnormal Program termination”。组件已经注册。
解决方案1:
gz
解决方案2: Header: Declared in objbase.h.
Library: Use ole32.lib.
用CoInitialize()
解决方案4: 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,
DWORD dwCoInit
);
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, or the thread that called CoInitializeEx currently belongs to the neutral threaded apartment.
Remarks
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.
Note You must include the #define _WIN32_DCOM preprocessor directive at the beginning of your code to be able to use CoInitializeEx.
A thread must call CoInitializeEx or CoInitialize before calling any other COM library function except the 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.
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 help protect the object's data.
When an object that is configured to run in the neutral threaded apartment (NTA) is called by a thread that is in either an STA or the MTA, that thread transfers to the NTA. If this thread subsequently calls CoInitializeEx, the call fails and returns RPC_E_CHANGED_MODE.
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 contr