Attributprogrammierung-FAQ
Dieses Thema beantwortet die folgenden häufig gestellter Fragen:
Was ist ein HRESULT?
Wann muss ich den Parameternamen für ein Attribut angegeben?
Kann ich Kommentare in einem Attributblock verwenden?
Wie die Interaktion mit Vererbung Attribute?
Wie kann ich Attribute in einem nicht attributiertes ATL-Projekt verwendet werden?
Wie kann ich eine IDL-Datei in einem attributierten Projekt verwendet werden?
Kann ich Code ändern, in dem von einem Attribut eingefügt wurde?
Wie kann ich weiterleiten deklariere eine attributierte Schnittstelle?
Kann ich Attribute für eine Klasse verwenden, die von einer Klasse abgeleitet ist, die auch Attribute verwendet werden?
Was ist ein HRESULT?
HRESULT ist ein einfacher Datentyp, der als Rückgabewert von ATL und Attribute im Allgemeinen häufig verwendet wird.Die folgende Tabelle beschreibt die verschiedenen Werte.Mehrere Werte werden in der Headerdatei winerror.h enthalten.
Name |
Beschreibung |
Wert |
---|---|---|
S_OK |
Vorgang erfolgreich |
0x00000000 |
E_UNEXPECTED |
Unerwarteter Fehler |
0x8000FFFF |
E_NOTIMPL |
Nicht implementiert. |
0x80004001 |
E_OUTOFMEMORY |
Fehlgeschlagene notwendigen Speicher belegen |
0x8007000E |
E_INVALIDARG |
Eine oder mehrere Argumente sind unzulässig |
0x80070057 |
E_NOINTERFACE |
Keine dieser Schnittstelle unterstützt |
0x80004002 |
E_POINTER |
Ungültiger Zeiger |
0x80004003 |
E_HANDLE |
Ungültiges Handle |
0x80070006 |
E_ABORT |
Vorgang abgebrochen |
0x80004004 |
E_FAIL |
Fehler Nicht angegeben |
0x80004005 |
E_ACCESSDENIED |
Allgemeiner Fehler verweigerte Zugriff |
0x80070005 |
Wann muss ich den Parameternamen für ein Attribut angegeben?
In den meisten Fällen wenn das Attribut über einen einzelnen Parameter verfügt, wird dieser Parameter benannt.Dieser Name ist nicht erforderlich, wenn er das Attribut im Code einfügt.Beispielsweise legt der folgende Verwendung des Attributs aggregierbar :
[coclass, aggregatable(value=allowed)]
class CMyClass
{
// The class declaration
};
exakt entspricht:
[coclass, aggregatable(allowed)]
class CMyClass
{
// The class declaration
};
Allerdings besitzen die folgenden Attribute der einzelnen unbenannten Parameter:
Kann ich Kommentare in einem Attributblock verwenden?
Sie können die einzeiligen und mehrzeiligen Kommentare innerhalb eines Attributblocks verwenden.Sie können jedoch jedes Format des Kommentars in Klammern verwenden, die die Parameter für ein Attribut enthalten.
Im Folgenden ist zulässig:
[ coclass,
progid("MyClass.CMyClass.1"), /* Multiple-line
comment */
threading("both") // Single-line comment
]
Im Folgenden wird nicht zulässig:
[ coclass,
progid("MyClass.CMyClass.1" /* Multiple-line comment */ ),
threading("both" // Single-line comment)
]
Wie die Interaktion mit Vererbung Attribute?
Sie können die attributierten und unattributed Klassen von anderen Klassen erben, die möglicherweise selbst oder nicht attributiert sind.Das Ergebnis der Berechnung von der attributierten Klasse entspricht dem die Ableitung von dieser Klasse, nach dem der Anbieter den Code Attribut umgewandelt wurde.Attribute sind nicht auf die abgeleitete Klassen von C++-Vererbung gesendet.Ein Attribut für Transformationen nur Code in der Nähe von ihren Attributen.
Wie kann ich Attribute in einem nicht attributiertes ATL-Projekt verwendet werden?
Sie haben möglicherweise ein nicht attributiertes ATL-Projekt, das eine IDL-Datei hat, und Sie sollten das Hinzufügen von attributierten Objekte beginnen.In diesem Fall verwenden Sie den Assistenten zum Hinzufügen von Klassen, um den Code bereitzustellen.
Wie kann ich eine IDL-Datei in einem attributierten Projekt verwendet werden?
Sie haben möglicherweise eine IDL-Datei, die Sie im attributierten Projekt ATL verwenden möchten.In diesem Fall würden Sie das Attribut importidl Kompilieren der IDL-Datei an eine H-Datei (siehe Eigenschaftenseiten " MIDL " im Dialogfeld Eigenschaftenseiten des Projekts) einschließen und dann die H-Datei im Projekt.
Kann ich Code ändern, in dem von einem Attribut eingefügt wurde?
Einige Attribute fügen Code in das Projekt ein.Sie können den eingefügten Code überprüfen, indem Sie die /Fx-Compileroption verwenden.Es ist auch möglich, Code von der eingefügte Datei zu kopieren und diesen in den Quellcode eingefügt werden soll.Dies ermöglicht es Ihnen, das Verhalten des Attributs zu ändern.Allerdings müssen Sie möglicherweise andere Teile des Codes ändern.
Im folgenden Beispiel ist das Ergebnis des Kopierens des eingefügten Codes in einer Quellcodedatei:
// 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() {}
Wie kann ich weiterleiten deklariere eine attributierte Schnittstelle?
Wenn Sie eine Vorwärtsdeklaration einer Schnittstelle mit Attributen vornehmen, müssen Sie dieselben Attribute der Vorwärtsdeklaration anwenden, die Sie zur eigentlichen Schnittstellendeklaration anwenden.Sie müssen das Exportieren auch Vorwärtsdeklaration Attribut anwenden.
Kann ich Attribute für eine Klasse verwenden, die von einer Klasse abgeleitet ist, die auch Attribute verwendet werden?
Nein, mithilfe von Attributen für eine Klasse, die von einer Klasse abgeleitet ist, die auch Attribute verwendet, wird nicht unterstützt.