你能有 2 个相同的 COM 对象吗?

Can you have 2 identical COM objects?

一个一般性问题,可以帮助回答我之前提出的另一个问题。我相信 COM 对象只是 return 一个指向创建对象的指针。因此,当我尝试两次初始化 COM 对象时,我是在我的应用程序中创建两个 COM 对象,还是创建指向同一对象的两个不同指针?或者可能有两个指针指向各自对象的对象副本?

// Pointer to WebViewController
static wil::com_ptr<ICoreWebView2Controller> webviewController;

// Pointer to WebView window
static wil::com_ptr<ICoreWebView2> webviewWindow;


// Locate the browser and set up the environment for WebView
CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
    Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
        [hWnd, url](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {

    // Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd
    env->CreateCoreWebView2Controller(hWnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
        [hWnd, url](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {

        _com_error err4(result);
        MessageBoxW(hWnd, L"Controller setup", 0, MB_OK);
        MessageBoxW(hWnd, err4.ErrorMessage(), 0, MB_OK);

        if (controller != nullptr) {
            webviewController = controller;
            webviewController->get_CoreWebView2(&webviewWindow);
        }

        // Add a few settings for the webview
        // The demo step is redundant since the values are the default settings
        ICoreWebView2Settings* Settings;
        webviewWindow->get_Settings(&Settings);
        Settings->put_IsScriptEnabled(TRUE);
        Settings->put_AreDefaultScriptDialogsEnabled(TRUE);
        Settings->put_IsWebMessageEnabled(TRUE);

        // Resize WebView to fit the bounds of the parent window
        RECT bounds;
        GetClientRect(hWnd, &bounds);
        webviewController->put_Bounds(bounds);

        // Schedule an async task to navigate to Bing
        webviewWindow->Navigate(url);
        if (GetWindow(hWnd, GW_CHILD) != NULL) {
            MessageBoxW(hWnd, L"not a NULL child window", 0, MB_OK);
        };

        // Step 4 - Navigation events

        // Step 5 - Scripting

        // Step 6 - Communication between host and web content

        return S_OK;
    }).Get());
    return S_OK;
}).Get());

我打电话了 CoInitialize(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); 前面的代码只有一次。我的问题是当我 运行 这个块两次时会发生什么?

So when I try to initialize a COM object twice, do I make two COM objects in my app, or do I make two different pointers to the same object? or perhaps there are two copies of the object that the pointers point to their respective objects?

这实际上取决于 COM 对象的实现。如果它被实现为单例,那么多次实例化它会 return 一个指向现有实例的指针(如果它不存在则创建一个新实例)。但是,如果 COM 对象没有实现为单例,那么每个实例化都会 return 一个指向新实例的指针。

My question is what happens when I run this block twice?

在这种特定情况下,执行代码两次将产生两个不同的 WebView2 实例。然后将两个实例分配给同一个 static 变量,导致一个实例不可撤销地泄露。

成为 XY Problem this information isn't terribly useful. The real issue you are trying to solve is knowing when the WebView2 control is fully constructed. That question has been answered .