Почему MSDN или VS2015 не объявляют методы IUnknown с соглашением __stdcall?

Извиняюсь, если этот вопрос немного не сфокусирован. Я работаю с COM, пишу несколько простых COM-серверов и объектов для сообщества Visual Studio 2015 под Windows 10. Все COM-объекты должны реализовывать интерфейс IUnknown. IDE VS2015 предложит реализовать виртуальные функции суперкласса. Итак, если я создаю "Example.h" с этим содержанием:

#include <Unknwn.h>

class MyClass : public IUnknown
{
};

А затем я выбираю Быстрые действия и рефакторинги.../ Внедряю все Pure Virtuals для класса "MyClass" из меню, вызываемого правой кнопкой мыши, я получаю некоторый сгенерированный код в моем файле.h:

#include <Unknwn.h>

class MyClass : public IUnknown
{
    // Inherited via IUnknown
    virtual HRESULT QueryInterface(REFIID riid, void ** ppvObject) override;
    virtual ULONG AddRef(void) override;
    virtual ULONG Release(void) override;
};

И VS2015 также предоставляет мне реализацию заглушки:

#include "stdafx.h"
#include "Example.h"

HRESULT MyClass::QueryInterface(REFIID riid, void ** ppvObject)
{
    return E_NOTIMPL;
}

ULONG MyClass::AddRef(void)
{
    return 0;
}

ULONG MyClass::Release(void)
{
    return 0;
}

Это хорошо, но не компилируется. Я получаю это сообщение об ошибке:

ошибка C2695: 'CFactory3::QueryInterface': переопределение виртуальной функции отличается от 'IUnknown::QueryInterface' только соглашением о вызовах

Я получаю это сообщение об ошибке для всех трех методов. Это имеет смысл, потому что фактическое объявление для каждого из этих методов определяет __stdcall Соглашение о вызовах. Теперь я могу добавить его в декларацию MyClass, как это:

virtual HRESULT __stdcall QueryInterface(REFIID riid, void ** ppvObject) override;
virtual ULONG __stdcall AddRef(void) override;
virtual ULONG __stdcall Release(void) override;

Это компилируется просто отлично.

Я знаю, какое соглашение о вызовах использовать, потому что, во-первых, когда я использую "Peek Definition", я вижу это:

virtual HRESULT STDMETHODCALLTYPE QueryInterface( 
            /* [in] */ REFIID riid,
            /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) = 0;

Развернув еще один уровень, я вижу, что STDMETHODCALLTYPE это просто макрос, определенный как __stdcall, Во-вторых, большая часть учебного материала, который я имею, рекомендует, чтобы методы IUnknown были реализованы с STDMETHODIMP макрос (который расширяется до HRESULT STDMETHODCALLTYPE).

Однако, когда я смотрю на страницу MSDN, посвященную методам IUnknown, не упоминается о необходимости какого-либо конкретного соглашения о вызовах.

Так что мне интересно, почему __stdcall соглашение не упомянуто на страницах MSDN для методов IUnknown, и почему IDE VS2015 не включил его в свои реализации заглушки IUnknown для моего подкласса.

В общем, как найти необходимое соглашение о вызовах для метода или функции, которые будут вызываться COM или любой другой частью Windows?

1 ответ

Решение

... из контекстного меню я получаю сгенерированный код в моем.h файле:

Проблема, с которой вы столкнулись, заключается в том, что Visual Studio IDE не соблюдает соглашение о вызовах существующего объявления интерфейса и генерирует код для соглашения о вызовах по умолчанию, а не __stdcall,

Таким образом, вы должны редактировать STDMETHOD и тебе хорошо идти оттуда. А также надеемся, что в следующей Visual Studio будут учтены правила вызова в инструментах генерации кода и рефакторинга.

__stdcall соглашение о вызовах используется для вызова функций Win32 API.

В основном это соглашение о вызовах является стандартным для всех методов COM (часто используется в макросах STDMETHOD, STDMETHOD_, STDMETHODCALLTYPE и т. д.), а также другие объявления API: CALLBACK, WINAPI решиться на __stdcall,

MSDN должен был быть более ясным о __stdcall и не предполагайте, что само собой разумеется

... некоторые необходимые детали соглашения о вызовах, такие как __stdcall опущены для этой иллюстрации...

И если у вас есть сомнения относительно соглашения об использовании в связи с Windows API, начните с __stdcall как это ваша лучшая ставка.

Другие вопросы по тегам