Aracılığıyla paylaş


Nasıl yapılır: Temsilcileri Tanımlama ve Kullanma (C++/CLI)

Bu makalede nasıl tanımlanacağını ve temsilciler de tüketen gösterir C++/CLI.

.net Framework temsilci sayısını sağlasa da, bazen yeni temsilciler tanımlamak olabilir.

Aşağıdaki kod örneği adlı bir temsilciyi tanımlar MyCallback.Olay işleme kodu — bu yeni temsilci harekete geçirilir, çağrılan işlev — dönüş türüne sahip olmalıdır void ve bir String başvuru.

Main işlevi tarafından tanımlanan statik bir yöntem kullanan SomeClass örneğini oluşturmak için MyCallback temsilcisi.Temsilci sonra dize "tek" temsilci nesnesini göndererek gösterildiği gibi bu işlevi çağırmak için farklı bir yöntem olur.Sonraki, ek örneklerini MyCallback birbirine bağlı ve sonra temsilci nesnesini bir çağrı tarafından yürütülür.

// 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;
}

Çıktı

  

Sonraki kod örneği, bir temsilci bir değer sınıfının bir üyesi ile ilişkilendirilecek gösterilmiştir.

// 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();
}

Çıktı

  

Temsilciler oluşturma hakkında

Kullanabileceğiniz "-" işleci bir bileşenin temsilci oluşan bir temsilciyi kaldırmak için.

// 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");
}

Çıktı

  
  
  
  
  

Bir temsilci geçti ^ Yerel işleve bir işlev işaretçisi bekler

Yönetilen bileşen burada yerel işlev üye işlevini yönetilen bileşenin temsilci sonra çağırabilir işlevi ile yerel bir işlev işaretçisi parametreleri çağırabilirsiniz.

Bu örnek, yerel işlev verir .dll oluşturur:

// 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");
   }
}

Sonraki örnek .dll tüketir ve temsilci tanıtıcı bir işlev işaretçisi beklediği Yerel işleve iletir.

// 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
}

Çıktı

  

Temsilciler yönetilmeyen işlevleri ile ilişkilendirmek için

Yerel işleve bir temsilci ilişkilendirmek için yerel işlev içinde yönetilen bir tür sarma ve üzerinden çağrılan işlev bildirmek 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;
}

Çıktı

  

İlişkisiz temsilcileri kullanmak için

İlişkisiz bir temsilci, temsilci çağrıldığında çağırmak istediğiniz işlevin türü örneği geçirmek için kullanabilirsiniz.

İlişkisiz temsilciler koleksiyonunda nesneler aracılığıyla yinelemek istiyorsanız kullanışlı — kullanarak Her, içinde anahtar sözcükler — ve her örnek üzerinde bir üye işlevini çağırın.

İşte nasıl bildirmek, başlatmak ve çağrı ilişkili ve ilişkisiz temsilciler:

Eylem

Bağlı temsilciler

İlişkisiz temsilciler

Bildirmek

Temsilci imzası temsilci çağırmak istediğiniz işlevin imzası eşleşmelidir.

Temsilci imza ilk parametresi türüdür this aramak istediğiniz nesne için.

İlk parametre sonra temsilci çağırmak istediğiniz işlevin imzası temsilci imza eşleşmesi gerekir.

Örneğini oluşturma

İlişkili bir temsilci örneğini oluşturma, örnek işlevi veya genel veya statik üye işlevi belirtebilirsiniz.

Örnek işlevini belirtmek için ilk parametre üye işlevini çağırmak istediğiniz türü örneği ve ikinci parametre çağırmak istediğiniz işlevin adresini.

Genel veya statik üye işlevini çağırın isterseniz, yalnızca genel bir işlevin adını veya statik üye işlev adını geçirin.

İlişkisiz bir temsilci örneğini oluşturma, yalnızca çağırmak istediğiniz işlevin adresini geçirin.

Call

Yalnızca ilişkili bir temsilciyi çağırdığınızda, temsilci imza tarafından gerekli olan parametreleri geçirin.

Bir sınır ile aynı temsilci, ancak ilk parametre çağırmak istediğiniz işlevin içeren nesnesinin bir örneği olması gerektiğini unutmayın.

Bu örnek nasıl bildirildiğini, örneğini oluşturma ve ilişkisiz temsilcileri çağırmak gösterilmiştir:

// 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();
}

Çıktı

  

Sonraki örnek ilişkisiz temsilciler nasıl gösterir ve Her, içinde anahtar sözcüklerini bir derlemedeki nesne yinelemenize ve her örnek üzerinde bir üye işlevini çağırın.

// 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();
}

Bu örnek, bir özelliğin erişimci işlevleri için ilişkisiz bir temsilci oluşturur:

// 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));
}

Çıktı

  

Aşağıdaki örnek, bir örneğe bağlı ve ilişkisiz bir örneği olduğu yerde bir çok noktaya yayın temsilci çaðrý yapýlacaðýný gösterir.

// 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);
};

Çıktı

  

Sonraki örnek oluşturma ve ilişkisiz bir genel temsilci çağırmak gösterilmiştir.

// 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) );
}

Çıktı

  

Ayrıca bkz.

Başvuru

temsilci (C++ Bileşen Uzantıları)