【发布时间】:2013-07-10 12:47:45
【问题描述】:
我正在学习 COM 的基础知识。现在我正在编写进程外服务器。 我编写了非常基本的服务器应用程序、dll/存根和客户端应用程序。
如果我注册服务器并使用进程内的 CoCreateInstance 创建对象的实例,它可以工作:
服务器/客户端:
int _tmain(int argc, _TCHAR* argv[])
{
IClassFactory *factory = new ISimpleServerFactory();
DWORD classToken;
::CoInitialize(NULL);
CoRegisterClassObject(
IID_ISimpleServer,
factory,
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&classToken);
ISimpleServer *pISimpleServer = NULL;
HRESULT hr = CoCreateInstance(
CLSID_CSimpleServer,
NULL,
CLSCTX_LOCAL_SERVER,
IID_ISimpleServer,
(void **)&pISimpleServer); //<===========SUCCESS
if(SUCCEEDED(hr))
printf("Instantiation successful\n");
if(pISimpleServer != NULL)
pISimpleServer->Release();
std::cin.ignore();
CoRevokeClassObject(classToken);
::CoUninitialize();
return 0;
}
现在我尝试将其拆分为单独的应用程序:
服务器:
int _tmain(int argc, _TCHAR* argv[])
{
IClassFactory *factory = new ISimpleServerFactory();
DWORD classToken;
::CoInitialize(NULL);
CoRegisterClassObject(
IID_ISimpleServer,
factory,
CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE,
&classToken);
if(SUCCEEDED(hr))
printf("Instantiation successful\n");
if(pISimpleServer != NULL)
pISimpleServer->Release();
std::cin.ignore();
CoRevokeClassObject(classToken);
::CoUninitialize();
return 0;
}
客户:
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
SimpleServer::ISimpleServer *pISimpleServer = NULL;
HRESULT hr = CoCreateInstance(
CLSID_CSimpleServer,
NULL,
CLSCTX_LOCAL_SERVER,
IID_ISimpleServer,
(void **)&pISimpleServer); // HERE IT HANGS
if (SUCCEEDED(hr))
{
//*****SMTH***
}
else
{
printf("Failed to load COM object (server not loaded?)\n");
}
if(pISimpleServer != NULL)
pISimpleServer->Release();
CoUninitialize();
std::cin.ignore();
return 0;
}
客户端在运行时挂起。 如果服务器没有启动,客户端类型“加载COM对象失败(服务器没有加载?)”,所以我想这不是服务器注册的问题。
但那会是什么呢?
【问题讨论】:
-
您的服务器没有发送消息。
-
这是什么意思?
-
在单线程单元中运行的线程(这是您在调用
::CoInitialize(NULL)时加入的)绝不能阻塞,而是必须运行消息泵 - 即调用GetMessage和DispatchMessage(至少)在一个循环中。传入的跨单元 COM 调用以窗口消息的形式发送到 STA 线程,该线程必须检索和处理。 -
需要有一种方法让服务器知道客户端正在连接。您对
cin.ignore()的调用会阻止服务器接收事件,因为它正忙于从cin读取。 COM不是魔法仙尘。为了处理 COM 事件,您需要为 COM 提供一种方法来控制您的线程。