com Out of Process Server(Clsctx_local_server)在MFC模态对话框中实现了



我已经创建了一个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

最新更新