我已经创建了一个com out Process Server。该服务器是一个默认的模态对话框,带有两个按钮" OK"one_answers" CANCAL"。
这就是我在CCOSTTESTAPP :: INTININSTANCE()
中注册流程外COM服务器的方式BOOL CCostTestApp::InitInstance()
{
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
//**Registering Out-of Process COM Server**
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Let's see if we were started by SCM.
//if(strstr(lpCmdLine, "/Embedding") || strstr(lpCmdLine, "-Embedding"))
if(cmdInfo.m_bRunEmbedded == TRUE)
{
CCostTestFactory costFactory;
HRESULT hr = CoRegisterClassObject(CLSID_CostTest, (IClassFactory*)&costFactory,
CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &m_RegID);
if ( FAILED(hr) )
{
CoUninitialize();
return FALSE;
}
}
CCostTestDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
我正在为此COM服务器创建客户端,作为控制台EXE,我将从中查询接口。
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
IUnknown* pIUnknow = NULL;
HRESULT hr = CoCreateInstance(CLSID_CostTest, NULL , CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pIUnknow);
if (NULL == pIUnknow)
{
cout<< "NULL Interface";
}
CoUninitialize();
return 0;
现在,cocreateinstance失败了,错误"服务器执行失败"
我进行了调试,服务器代码,并发现服务器被正确注册为CoreGisterClassObject()返回S_OK,我将获得类对象。
但是,此后,当它尝试创建对话框时,使用domodal(),它将消息泵入循环时,此后,带有ID" 49214"的第一条消息是成功的ID" 1024"。这引发了一个例外" costtest.exe中的0xffffffff in 0xffffff:0xc0000005:访问违规。"
我第一次实施COM服务器时完全迷失了。
另外,如果我将COM服务器创建为简单的控制台EXE,它可以工作!
请帮助我理解。
{ CCostTestFactory costFactory; HRESULT hr = CoRegisterClassObject(CLSID_CostTest, (IClassFactory*)&costFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &m_RegID); }
您将COM运行时指向局部变量。此后不久,该变量脱离了范围并被摧毁,使系统带有一个悬空的指针。然后,该系统通过悬挂指针调用方法, boom 。