【发布时间】: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->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对象被创建
标签: c++ visual-studio-2010 visual-studio-2008 atl dcom