Поделиться через


Атрибутивное программирование. Часто задаваемые вопросы

В этом разделе будет отвечать на следующие вопросы и ответы.

  • Что значение HRESULT?

  • При должен указывать имя параметра для атрибута?

  • Можно использовать комментарии в блоке атрибутов?

  • Как атрибуты взаимодействуют с наследованием?

  • Как использовать атрибуты в неатрибутированные проекте библиотеки ATL?

  • Как использовать idl-файл проекта в приписанном?

  • Можно изменить код, впрыснут атрибутом?

  • Как объявляю переадресованы с атрибутами интерфейс?

  • Можно использовать атрибуты в классе, производном от класса, также используются атрибуты?

Что значение HRESULT?

HRESULT простой тип данных, который часто используется как возвращаемое значение атрибутами и библиотеки ATL. В следующей таблице описываются различные значения. Несколько значений, содержащихся в файле заголовка winerror.h.

Имя

Описание

Значение

S_OK

Успешная операция

0x00000000

E_UNEXPECTED

Непредвиденный сбой

0x8000FFFF

E_NOTIMPL

Не реализовано

0x80004001

E_OUTOFMEMORY

Не удалось выделить необходимую память

0x8007000E

E_INVALIDARG

Один или несколько аргументов являются недопустимыми

0x80070057

E_NOINTERFACE

Нет такого поддерживаемого интерфейса

0x80004002

E_POINTER

Недопустимый указатель

0x80004003

E_HANDLE

Недопустимый дескриптор

0x80070006

E_ABORT

Операция прерватьая

0x80004004

E_FAIL

Неуказанный ошибка

0x80004005

E_ACCESSDENIED

Без ограничений к было отказано ошибка

0x80070005

При должен указывать имя параметра для атрибута?

В большинстве случаев если атрибут имеет единственный параметр, что параметр имеет имя. Это имя необходимо вводить атрибут в код. Например, следующее потребление aggregatable атрибут:

[coclass, aggregatable(value=allowed)]
class CMyClass
{
// The class declaration
};

точно такое же, как:

[coclass, aggregatable(allowed)]
class CMyClass
{
// The class declaration
};

Однако следующие атрибуты имеют отдельные неименованные параметры:

call_as

case

cpp_quote

default

defaultvalue

defaultvtable

emitidl

запись

first_is

helpcontext

helpfile

helpstring

helpstringcontext

helpstringdll

id

iid_is

import

importlib

include

includelib

last_is

length_is

max_is

no_injected_text

pointer_default

директива pragma

restricted

size_is

source

switch_is

switch_type

transmit_as

wire_marshal

Можно использовать комментарии в блоке атрибутов?

Можно использовать и одностроковые и многономенклатурные комментарии внутри блока атрибута. Однако нельзя использовать любой стиль комментариев внутри скобок, содержащая параметры, к атрибуту.

Допускается следующее:

[ coclass,
   progid("MyClass.CMyClass.1"), /* Multiple-line
                                       comment */
   threading("both") // Single-line comment
]

Следующее disallowed:

[ coclass,
   progid("MyClass.CMyClass.1" /* Multiple-line comment */ ),
   threading("both" // Single-line comment)
]

Как атрибуты взаимодействуют с наследованием?

Можно наследовать и приписанные и unattributed классы из других классов, которые сами могут быть приписаны или нет. Результат наследование от класса с атрибутом совпадает с выводящ от класса после того как поставщик атрибута преобразовал его код. Атрибуты не передаются в производных классах посредством наследования C++. Поставщик атрибута только преобразует код в его атрибутов.

Как использовать атрибуты в неатрибутированные проекте библиотеки ATL?

Можно использовать представляет проект библиотеки ATL, который имеет idl-файл и можно начать добавление приписанные объекты. В этом случае используйте мастер добавления классов, чтобы предоставить код.

Как использовать idl-файл проекта в приписанном?

Можно использовать idl-файл, который необходимо использовать в проекте приписанном библиотеки ATL. В этом случае класс importidl атрибут будет компилироваться idl-файл в h-файл (см. Cтраницы свойств MIDL в диалоговом окне страницы свойств проекта), а затем включите h-файл в проекте.

Можно изменить код, впрыснут атрибутом?

Некоторые атрибуты впрыскивают код в проект. Можно просмотреть с помощью введенного кода /Fx параметр компилятора. Также можно скопировать код из впрыснутого файла и вставить его в свой исходный код. Это позволяет изменять поведение атрибута. Однако можно изменить другие части кода.

Следующий пример кода впрыснутого результат копированием в файл исходного кода.

// attr_injected.cpp
// compile with: comsupp.lib
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>

[ module(name="MyLibrary") ];

// ITestTest
[ 
   object,
   uuid("DADECE00-0FD2-46F1-BFD3-6A0579CA1BC4"),
   dual,
   helpstring("ITestTest Interface"),
   pointer_default(unique)
]

__interface ITestTest : IDispatch {
   [id(1), helpstring("method DoTest")] 
   HRESULT DoTest([in] BSTR str);
};

// _ITestTestEvents
[
   uuid("12753B9F-DEF4-49b0-9D52-A79C371F2909"),
   dispinterface,
   helpstring("_ITestTestEvents Interface")
]

__interface _ITestTestEvents {
   [id(1), helpstring("method BeforeChange")] HRESULT BeforeChange([in] BSTR str, [in,out] VARIANT_BOOL* bCancel);
};

// CTestTest
[
   coclass,
   threading(apartment),
   vi_progid("TestATL1.TestTest"),
   progid("TestATL1.TestTest.1"),
   version(1.0),
   uuid("D9632007-14FA-4679-9E1C-28C9A949E784"),
   // this line would be commented out from original file
   // event_source("com"),
   // this line would be added to support injected code
   source(_ITestTestEvents),
   helpstring("TestTest Class")
]

class ATL_NO_VTABLE CTestTest : public ITestTest,
// the following base classes support added injected code
public IConnectionPointContainerImpl<CTestTest>,
public IConnectionPointImpl<CTestTest, &__uuidof(::_ITestTestEvents), CComDynamicUnkArray>
{
public:
   CTestTest() {
   }
   // this line would be commented out from original file
   // __event __interface _ITestTestEvents;
   DECLARE_PROTECT_FINAL_CONSTRUCT()
   HRESULT FinalConstruct() {
      return S_OK;
   }

void FinalRelease() {}

public:
   CComBSTR m_value;
   STDMETHOD(DoTest)(BSTR str) {
      VARIANT_BOOL bCancel = FALSE;
      BeforeChange(str,&bCancel);
      if (bCancel) {
          return Error("Error : Someone don't want us to change the value");
      }

     m_value =str;
     return S_OK;
    }
// the following was copied in from the injected code.
HRESULT BeforeChange(::BSTR i1,::VARIANT_BOOL* i2) {
   HRESULT hr = S_OK;
   IConnectionPointImpl<CTestTest, &__uuidof(_ITestTestEvents), CComDynamicUnkArray>* p = this;
   VARIANT rgvars[2];
   Lock();
   IUnknown** pp = p->m_vec.begin();
   Unlock();
   while (pp < p->m_vec.end()) {
      if (*pp != NULL) {
         IDispatch* pDispatch = (IDispatch*) *pp;
         ::VariantInit(&rgvars[1]);
         rgvars[1].vt = VT_BSTR;
         V_BSTR(&rgvars[1])= (BSTR) i1;
         ::VariantInit(&rgvars[0]);
         rgvars[0].vt = (VT_BOOL | VT_BYREF);
         V_BOOLREF(&rgvars[0])= (VARIANT_BOOL*) i2;
         DISPPARAMS disp = { rgvars, NULL, 2, 0 };
         VARIANT ret_val;
         hr = __ComInvokeEventHandler(pDispatch, 1, 1, &disp, &ret_val);
         if (FAILED(hr))
            break;
      }
      pp++;
   }
   return hr;
}

BEGIN_CONNECTION_POINT_MAP(CTestTest)
CONNECTION_POINT_ENTRY(__uuidof(::_ITestTestEvents))
END_CONNECTION_POINT_MAP()
// end added code section

// _ITestCtrlEvents Methods
public:
};

int main() {}

Как объявляю переадресованы с атрибутами интерфейс?

Если планируется сделать переднее объявление интерфейса с атрибутом, необходимо применить те же атрибуты к объявлению переднему, которые применяются к фактическому объявление интерфейса. Необходимо также применить экспорт атрибут к вашему переднему объявлению.

Можно использовать атрибуты в классе, производном от класса, также используются атрибуты?

Не поддерживается нет, используя атрибуты в классе, производном от класса, также используются атрибуты.

См. также

Другие ресурсы

Основные понятия атрибутивного программирования