【问题标题】:CoCreateInstance hangs in single-threaded exe COM clientCoCreateInstance 在单线程 exe COM 客户端中挂起
【发布时间】: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) 时加入的)绝不能阻塞,而是必须运行消息泵 - 即调用 GetMessageDispatchMessage(至少)在一个循环中。传入的跨单元 COM 调用以窗口消息的形式发送到 STA 线程,该线程必须检索和处理。
  • 需要有一种方法让服务器知道客户端正在连接。您对cin.ignore() 的调用会阻止服务器接收事件,因为它正忙于从cin 读取。 COM不是魔法仙尘。为了处理 COM 事件,您需要为 COM 提供一种方法来控制您的线程。

标签: c++ com


【解决方案1】:

好的,就像 Raymond 指出的那样,我的服务器没有发送消息。我加了

MSG msg;
while (GetMessage(&msg, 0, 0, 0) > 0) 
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    if(_kbhit())
        break;
}

进入服务器主体,它变得更好了:)

【讨论】:

    猜你喜欢
    • 2017-08-30
    • 2016-02-23
    • 1970-01-01
    • 2011-03-13
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 2016-01-15
    相关资源
    最近更新 更多