C ++ (ATL) ITypeInfo.GetContainedTypeLib завершается ошибкой при передаче живого экземпляра класса VBA - PullRequest
0 голосов
/ 04 сентября 2018

Итак, я задал этот вопрос в контексте C #, и у меня установлено значение bounty .

Я написал эквивалентный фрагмент кода C ++ (который будет размещен в проекте DLL ATL), чтобы также использовать опыт разработчиков C ++.

В IDispatch есть метод GetTypeInfo (), с помощью которого можно получить указатель на ITypeInfo. У самого ITypeInfo есть метод GetContainedTypeLib, который получает содержащий ITypeLib (как говорится). Это полезно, когда данный экземпляр CoClass один раз может получить доступ ко всем другим классам CoClass в данной DLL, что очень полезно для размышлений.

Я задавался вопросом, будет ли Excel VBA взаимодействовать аналогичным образом и возвращать ITypeLib для содержащего проекта VBA и в равной степени позволять мне повторять все найденные в нем типы. Итак, я написал тестовый код C #, и это связано. Здесь я даю эквивалентный код C ++ для использования опыта C ++.

ИДЛ ...

[
    object,
    uuid(ddc4e135-49d6-49f8-ad57-ded4180095fd),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface ICoClassGetContainingTypeLib : IDispatch
{
    HRESULT GetContainingTypeLib(IDispatch* vbaClass, IUnknown** iunkTypeLib);
};

[
    uuid(bc8410a6-802a-4f91-a73b-c03179bb402b)
]
coclass CoClassGetContainingTypeLib
{
    [default] interface ICoClassGetContainingTypeLib;
};

Реализация метода cpp

STDMETHODIMP CCoClassGetContainingTypeLib::GetContainingTypeLib(IDispatch* vbaClass, IUnknown** iunkTypeLib)
{
    CComPtr<IDispatch> itfDispatch(vbaClass);
    CComPtr<ITypeInfo> pITypeInfo;

    HRESULT hr = S_OK;
    HRESULT hr2 = S_OK;
    try
    {

        hr = itfDispatch->GetTypeInfo(0, 0, &pITypeInfo);
        if (SUCCEEDED(hr)) 
        {
            UINT* idx(0);
            CComQIPtr<ITypeLib> pTLib;
            HRESULT hr2 = pITypeInfo->GetContainingTypeLib(&pTLib, idx);
            return hr2; // throws exception Exception 0x800A88C1 
            // which ends u[p at 35009

            //TODO If successful copy to ByRef param  iunkTypeLib
        }
    }
    catch (std::exception ex)
    {
        return E_FAIL;
    }
    return S_OK;
}

И заголовок объявления

STDMETHOD(GetContainingTypeLib)(IDispatch* vbaClass, IUnknown** iunkTypeLib);

И какой-нибудь клиент VBA

Sub TestGetContainingTypeLib()

    Dim oTR As ToolsReferences  '* could be ANY VBA class
    Set oTR = New ToolsReferences   '* could be ANY VBA class

    '* instantiate my ATL project
    Dim oTest As GetContainingTypeLibTestLib.CoClassGetContainingTypeLib
    Set oTest = New GetContainingTypeLibTestLib.CoClassGetContainingTypeLib

    Dim iunkTypeLib As IUnknown
    Set iunkTypeLib = Nothing   '* not strictly required
    Call oTest.GetContainingTypeLib(oTR, iunkTypeLib)

End Sub

В Интернете очень мало объяснений относительно номера исключения 0x800A88C1. Я думаю, что команда Excel сказала нет.

...