Атрибутивное программирование. Часто задаваемые вопросы
В этом разделе будет отвечать на следующие вопросы и ответы.
Что значение 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
};
Однако следующие атрибуты имеют отдельные неименованные параметры:
Можно использовать комментарии в блоке атрибутов?
Можно использовать и одностроковые и многономенклатурные комментарии внутри блока атрибута. Однако нельзя использовать любой стиль комментариев внутри скобок, содержащая параметры, к атрибуту.
Допускается следующее:
[ 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() {}
Как объявляю переадресованы с атрибутами интерфейс?
Если планируется сделать переднее объявление интерфейса с атрибутом, необходимо применить те же атрибуты к объявлению переднему, которые применяются к фактическому объявление интерфейса. Необходимо также применить экспорт атрибут к вашему переднему объявлению.
Можно использовать атрибуты в классе, производном от класса, также используются атрибуты?
Не поддерживается нет, используя атрибуты в классе, производном от класса, также используются атрибуты.