VS 2010 Build 中的 ATL DCOM 对象创建失败

Posted

技术标签:

【中文标题】VS 2010 Build 中的 ATL DCOM 对象创建失败【英文标题】:ATL DCOM Object creation fails in VS 2010 Build 【发布时间】:2012-09-17 04:22:21 【问题描述】:

我们有一个 DCOM 服务器,可以在 VS 2008 构建的 Win 7 64 位中正常工作。在 VS 2010 构建的情况下,客户端对象创建失败并显示“服务器创建失败”错误消息。类定义如下。

调试时,我们看到在消息循环中收到了一条消息 id 为 1024 的消息,但 DispatchMessage 并没有路由该消息,而是创建了 CICEConnect 对象。在 VS 2008 版本中,DispatchMessage 将调用路由到创建 CICEConnect 对象。我相信这会造成问题

当客户端尝试创建对象时,服务器应用程序被声明。 DCOM 服务器正在本地机器上运行

如何进一步调试问题?

void RunMessageLoop() throw()
      
            MSG msg;
            while (GetMessage(&msg, 0, 0, 0) > 0)
            
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
            
      

class ATL_NO_VTABLE CICEConnect :
      public CComObjectRootEx<CComMultiThreadModel>,
      public CComCoClass<CICEConnect, &CLSID_ICEConnect>,
      public IDispatchImpl<IICEConnect, &IID_IICEConnect, &LIBID_ICEConnectServerLib, /*wMajor =*/ 1, /*wMinor =*/ 0>

public:
      CICEConnect()
      
      
      DECLARE_CLASSFACTORY_SINGLETON(CICEConnect)
DECLARE_REGISTRY_RESOURCEID(IDR_ICECONNECT)


BEGIN_COM_MAP(CICEConnect)
      COM_INTERFACE_ENTRY(IICEConnect)
      COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

;

如果我在以下RegisterClassObject 中跳过p-&gt;Release();,则COM 对象创建成功。

struct _ATL_OBJMAP_ENTRY30

       HRESULT WINAPI RegisterClassObject(
              _In_ DWORD dwClsContext,
              _In_ DWORD dwFlags)
       
              IUnknown* p = NULL;
              if (pfnGetClassObject == NULL)
                     return S_OK;
              HRESULT hRes = pfnGetClassObject(pfnCreateInstance, __uuidof(IUnknown), (LPVOID*) &p);
              if (SUCCEEDED(hRes))
                     hRes = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister);
              if (p != NULL)
                     p->Release();
              return hRes;
       
// Added in ATL 3.0
       void (WINAPI *pfnObjectMain)(_In_ bool bStarting);
;

下面给出了用于创建 COM 对象的代码

int _tmain(int argc, _TCHAR* argv[])

      CoInitializeEx(NULL,COINIT_MULTITHREADED);

                      COSERVERINFO server;
                      memset(&server,0,sizeof(COSERVERINFO));
                      COAUTHINFO athn;
                      ZeroMemory(&athn, sizeof(COAUTHINFO));
                      athn.dwAuthnLevel = RPC_C_AUTHN_LEVEL_NONE;
                      athn.dwAuthnSvc = RPC_C_AUTHN_WINNT;
                      athn.dwAuthzSvc = RPC_C_AUTHZ_NONE;
                      athn.dwCapabilities = EOAC_NONE;
                      athn.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
                      athn.pAuthIdentityData = NULL;
                      athn.pwszServerPrincName = NULL;
                      server.pAuthInfo = &athn;
                      server.pwszName = L"\\\\localhost";
                      server.dwReserved1 = 0;
                      server.dwReserved2 = 0;
                      MULTI_QI mqi = &IID_IICEConnect, NULL, S_OK;

                      // Access the PMC on the given machine
                        HRESULT hRes = CoCreateInstanceEx(CLSID_ICEConnect,NULL,
                                        CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER,&server,1,&mqi);
      return 0;

【问题讨论】:

你进一步调试是看你的服务器端有什么活动:1 是否曾调用过CICEConnect::CICEConnect()2 是否曾调用过它的类工厂IClassFactory::CreateInstance IClassFactory::CreateInstance 没有被调用,但是类工厂对象被创建了 这表明类实现本身没有问题。阻止实例化的是安全性或 coclass 注册。 用一些额外的信息更新了我的帖子。如果我注释类工厂对象的对象释放注册后,COM对象被创建 【参考方案1】:

你不觉得DispatchMessage是一个系统调用,它的实现超出了VS2008 & VS2010的控制范围吗?也许您没有处理正确的消息来创建控件!例如,SDK 中的更改可能会产生您的错误。 ID 为 1024 的消息是WM_USER,系统无法正常处理。处理此消息取决于用户代码

【讨论】:

以上是关于VS 2010 Build 中的 ATL DCOM 对象创建失败的主要内容,如果未能解决你的问题,请参考以下文章

在 CI 服务器上构建 ATL VS2010 项目

当项目名称带有连字符时,为啥 VS 2010 ATL 简单对象向导不会生成 .cpp/.h 文件?

ATL 中的 CImage 类

从 COM 到 DCOM

VS2017 ATL创建ActiveX编程要点

_ATL_ALLOW_UNSIGNED_CHAR 啥时候可以工作?