Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit artikel wordt beschreven hoe u gemachtigden definieert en gebruikt in C++/CLI.
Hoewel .NET Framework een aantal gemachtigden biedt, moet u soms nieuwe gemachtigden definiëren.
In het volgende codevoorbeeld wordt een gemachtigde gedefinieerd met de naam MyCallback. De gebeurtenisafhandelingscode (de functie die wordt aangeroepen wanneer deze nieuwe delegeerder wordt geactiveerd) moet een retourtype void hebben en een String verwijzing hebben.
De hoofdfunctie maakt gebruik van een statische methode, gedefinieerd door SomeClass, om de gedelegeerde MyCallback te instantiëren. De gemachtigde wordt vervolgens een alternatieve methode voor het aanroepen van deze functie, zoals wordt gedemonstreerd door de tekenreeks 'één' naar het gemachtigde object te verzenden. Vervolgens worden extra exemplaren van MyCallback elkaar gekoppeld en vervolgens uitgevoerd door één aanroep naar het gedelegeerde-object.
// use_delegate.cpp
// compile with: /clr
using namespace System;
ref class SomeClass
{
public:
static void Func(String^ str)
{
Console::WriteLine("static SomeClass::Func - {0}", str);
}
};
ref class OtherClass
{
public:
OtherClass( Int32 n )
{
num = n;
}
void Method(String^ str)
{
Console::WriteLine("OtherClass::Method - {0}, num = {1}",
str, num);
}
Int32 num;
};
delegate void MyCallback(String^ str);
int main( )
{
MyCallback^ callback = gcnew MyCallback(SomeClass::Func);
callback("single");
callback += gcnew MyCallback(SomeClass::Func);
OtherClass^ f = gcnew OtherClass(99);
callback += gcnew MyCallback(f, &OtherClass::Method);
f = gcnew OtherClass(100);
callback += gcnew MyCallback(f, &OtherClass::Method);
callback("chained");
return 0;
}
static SomeClass::Func - single
static SomeClass::Func - chained
static SomeClass::Func - chained
OtherClass::Method - chained, num = 99
OtherClass::Method - chained, num = 100
In het volgende codevoorbeeld ziet u hoe u een gemachtigde koppelt aan een lid van een waardeklasse.
// mcppv2_del_mem_value_class.cpp
// compile with: /clr
using namespace System;
public delegate void MyDel();
value class A {
public:
void func1() {
Console::WriteLine("test");
}
};
int main() {
A a;
A^ ah = a;
MyDel^ f = gcnew MyDel(a, &A::func1); // implicit box of a
f();
MyDel^ f2 = gcnew MyDel(ah, &A::func1);
f2();
}
test
test
Delegaten samenstellen
U kunt de "operator" '-' gebruiken om een componentdelegate te verwijderen uit een samengestelde delegate.
// mcppv2_compose_delegates.cpp
// compile with: /clr
using namespace System;
delegate void MyDelegate(String ^ s);
ref class MyClass {
public:
static void Hello(String ^ s) {
Console::WriteLine("Hello, {0}!", s);
}
static void Goodbye(String ^ s) {
Console::WriteLine(" Goodbye, {0}!", s);
}
};
int main() {
MyDelegate ^ a = gcnew MyDelegate(MyClass::Hello);
MyDelegate ^ b = gcnew MyDelegate(MyClass::Goodbye);
MyDelegate ^ c = a + b;
MyDelegate ^ d = c - a;
Console::WriteLine("Invoking delegate a:");
a("A");
Console::WriteLine("Invoking delegate b:");
b("B");
Console::WriteLine("Invoking delegate c:");
c("C");
Console::WriteLine("Invoking delegate d:");
d("D");
}
Uitvoer
Invoking delegate a:
Hello, A!
Invoking delegate b:
Goodbye, B!
Invoking delegate c:
Hello, C!
Goodbye, C!
Invoking delegate d:
Goodbye, D!
Geef een delegate^ door aan een systeemeigen functie die een functie-pointer verwacht
Vanuit een beheerd onderdeel kunt u een systeemeigen functie aanroepen met functiepointerparameters waarbij de systeemeigen functie vervolgens de lidfunctie van de gemachtigde van het beheerde onderdeel kan aanroepen.
In dit voorbeeld wordt de .dll gemaakt waarmee de systeemeigen functie wordt geëxporteerd:
// delegate_to_native_function.cpp
// compile with: /LD
#include < windows.h >
extern "C" {
__declspec(dllexport)
void nativeFunction(void (CALLBACK *mgdFunc)(const char* str)) {
mgdFunc("Call to Managed Function");
}
}
In het volgende voorbeeld wordt de .dll gebruikt en wordt een gedelegeerde handle doorgegeven aan de systeemeigen functie die een functiepointer verwacht.
// delegate_to_native_function_2.cpp
// compile with: /clr
using namespace System;
using namespace System::Runtime::InteropServices;
delegate void Del(String ^s);
public ref class A {
public:
void delMember(String ^s) {
Console::WriteLine(s);
}
};
[DllImportAttribute("delegate_to_native_function", CharSet=CharSet::Ansi)]
extern "C" void nativeFunction(Del ^d);
int main() {
A ^a = gcnew A;
Del ^d = gcnew Del(a, &A::delMember);
nativeFunction(d); // Call to native function
}
Uitvoer
Call to Managed Function
Gemachtigden koppelen aan niet-beheerde functies
Als u een gemachtigde wilt koppelen aan een systeemeigen functie, moet u de systeemeigen functie verpakken in een beheerd type en declareren dat de functie moet worden aangeroepen via PInvoke.
// mcppv2_del_to_umnangd_func.cpp
// compile with: /clr
#pragma unmanaged
extern "C" void printf(const char*, ...);
class A {
public:
static void func(char* s) {
printf(s);
}
};
#pragma managed
public delegate void func(char*);
ref class B {
A* ap;
public:
B(A* ap):ap(ap) {}
void func(char* s) {
ap->func(s);
}
};
int main() {
A* a = new A;
B^ b = gcnew B(a);
func^ f = gcnew func(b, &B::func);
f("hello");
delete a;
}
Uitvoer
hello
Niet-afhankelijke gemachtigden gebruiken
U kunt een ongebonden gedelegeerde gebruiken om een instantie van het type door te geven waarvan u de functie wilt aanroepen wanneer de gedelegeerde wordt aangeroepen.
Onafhankelijke gedelegeerden zijn vooral handig als u de objecten in een verzameling wilt doorlopen met behulp van de voor elk, in en een lidfunctie aanroepen voor elk exemplaar.
U kunt als volgt afhankelijke en niet-afhankelijke gemachtigden declareren, instantiëren en aanroepen:
| Handeling | Gebonden gemachtigden | Ongebonden gedelegeerden |
|---|---|---|
| Verklaren | De handtekening van de gemachtigde moet overeenkomen met de handtekening van de functie die u wilt aanroepen via de gemachtigde. | De eerste parameter van de delegeraathandtekening is het type this voor het object dat u wilt aanroepen.Na de eerste parameter moet de handtekening van de gemachtigde overeenkomen met de handtekening van de functie die u wilt aanroepen via de gemachtigde. |
| Instantiëren | Wanneer u een afhankelijke gemachtigde instantieert, kunt u een exemplaarfunctie of een globale of statische lidfunctie opgeven. Als je een instantie-functie wilt opgeven, is de eerste parameter een instantie van het type waarvan je de instantie-functie wilt aanroepen en de tweede parameter is het adres van de functie die je wilt aanroepen. Als u een globale of statische lidfunctie wilt aanroepen, geeft u de naam van een globale functie of de naam van de statische lidfunctie door. |
Wanneer u een niet-afhankelijke gemachtigde instantieert, geeft u alleen het adres door van de functie die u wilt aanroepen. |
| Oproep | Wanneer u een afhankelijke gemachtigde aanroept, geeft u de parameters door die vereist zijn voor de handtekening van de gemachtigde. | Hetzelfde als een afhankelijke gemachtigde, maar vergeet niet dat de eerste parameter een exemplaar moet zijn van het object dat de functie bevat die u wilt aanroepen. |
In dit voorbeeld ziet u hoe u niet-afhankelijke gemachtigden declareert, instantiëren en aanroept:
// unbound_delegates.cpp
// compile with: /clr
ref struct A {
A(){}
A(int i) : m_i(i) {}
void Print(int i) { System::Console::WriteLine(m_i + i);}
private:
int m_i;
};
value struct V {
void Print() { System::Console::WriteLine(m_i);}
int m_i;
};
delegate void Delegate1(A^, int i);
delegate void Delegate2(A%, int i);
delegate void Delegate3(interior_ptr<V>);
delegate void Delegate4(V%);
delegate void Delegate5(int i);
delegate void Delegate6();
int main() {
A^ a1 = gcnew A(1);
A% a2 = *gcnew A(2);
Delegate1 ^ Unbound_Delegate1 = gcnew Delegate1(&A::Print);
// delegate takes a handle
Unbound_Delegate1(a1, 1);
Unbound_Delegate1(%a2, 1);
Delegate2 ^ Unbound_Delegate2 = gcnew Delegate2(&A::Print);
// delegate takes a tracking reference (must deference the handle)
Unbound_Delegate2(*a1, 1);
Unbound_Delegate2(a2, 1);
// instantiate a bound delegate to an instance member function
Delegate5 ^ Bound_Del = gcnew Delegate5(a1, &A::Print);
Bound_Del(1);
// instantiate value types
V v1 = {7};
V v2 = {8};
Delegate3 ^ Unbound_Delegate3 = gcnew Delegate3(&V::Print);
Unbound_Delegate3(&v1);
Unbound_Delegate3(&v2);
Delegate4 ^ Unbound_Delegate4 = gcnew Delegate4(&V::Print);
Unbound_Delegate4(v1);
Unbound_Delegate4(v2);
Delegate6 ^ Bound_Delegate3 = gcnew Delegate6(v1, &V::Print);
Bound_Delegate3();
}
Uitvoer
2
3
2
3
2
7
8
7
8
7
In het volgende voorbeeld ziet u hoe u niet-gebonden gedelegeerden en de for each, in trefwoorden gebruikt om objecten in een verzameling te doorlopen en een memberfunctie aan te roepen voor elk exemplaar.
// unbound_delegates_2.cpp
// compile with: /clr
using namespace System;
ref class RefClass {
String^ _Str;
public:
RefClass( String^ str ) : _Str( str ) {}
void Print() { Console::Write( _Str ); }
};
delegate void PrintDelegate( RefClass^ );
int main() {
PrintDelegate^ d = gcnew PrintDelegate( &RefClass::Print );
array< RefClass^ >^ a = gcnew array<RefClass^>( 10 );
for ( int i = 0; i < a->Length; ++i )
a[i] = gcnew RefClass( i.ToString() );
for each ( RefClass^ R in a )
d( R );
Console::WriteLine();
}
In dit voorbeeld wordt een niet-afhankelijke gemachtigde gemaakt voor de toegangsfunctie van een eigenschap:
// unbound_delegates_3.cpp
// compile with: /clr
ref struct B {
property int P1 {
int get() { return m_i; }
void set(int i) { m_i = i; }
}
private:
int m_i;
};
delegate void DelBSet(B^, int);
delegate int DelBGet(B^);
int main() {
B^ b = gcnew B;
DelBSet^ delBSet = gcnew DelBSet(&B::P1::set);
delBSet(b, 11);
DelBGet^ delBGet = gcnew DelBGet(&B::P1::get);
System::Console::WriteLine(delBGet(b));
}
Uitvoer
11
In het volgende voorbeeld ziet u hoe u een multicastdelegatie aanroept, waarbij één exemplaar afhankelijk is en één exemplaar niet afhankelijk is.
// unbound_delegates_4.cpp
// compile with: /clr
ref class R {
public:
R(int i) : m_i(i) {}
void f(R ^ r) {
System::Console::WriteLine("in f(R ^ r)");
}
void f() {
System::Console::WriteLine("in f()");
}
private:
int m_i;
};
delegate void Del(R ^);
int main() {
R ^r1 = gcnew R(11);
R ^r2 = gcnew R(12);
Del^ d = gcnew Del(r1, &R::f);
d += gcnew Del(&R::f);
d(r2);
}
Uitvoer
in f(R ^ r)
in f()
In het volgende voorbeeld ziet u hoe u een niet-afhankelijke algemene gemachtigde maakt en aanroept.
// unbound_delegates_5.cpp
// compile with: /clr
ref struct R {
R(int i) : m_i(i) {}
int f(R ^) { return 999; }
int f() { return m_i + 5; }
int m_i;
};
value struct V {
int f(V%) { return 999; }
int f() { return m_i + 5; }
int m_i;
};
generic <typename T>
delegate int Del(T t);
generic <typename T>
delegate int DelV(T% t);
int main() {
R^ hr = gcnew R(7);
System::Console::WriteLine((gcnew Del<R^>(&R::f))(hr));
V v;
v.m_i = 9;
System::Console::WriteLine((gcnew DelV<V >(&V::f))(v) );
}
Uitvoer
12
14