방법: 대리자 정의 및 사용(C++/CLI)

이 문서에서는 정의 하 고 대리자를 사용 하는 방법을 보여 줍니다. C++/CLI.

.NET Framework 대리자를 제공 하지만 때로는 새 대리자를 정의 해야 합니다.

라는 대리자를 정의 하는 다음 코드 예제에서는 MyCallback.이벤트 처리 코드-새 대리자가 발생 될 때 호출 되는 함수-반환 형식이 있어야 합니다 void 고은 String 참조.

Main 함수가 정의 되는 정적 메서드를 사용 하 여 SomeClass 인스턴스화하는 MyCallback 대리자입니다.그런 다음 대리자 문자열 "단일" 대리자 개체를 보내서 같이이 함수를 호출 하는 방법도 됩니다.다음 추가 인스턴스를 MyCallback 함께 연결 되 고 그런 다음 대리자 개체를 한 번 호출 하 여 실행 합니다.

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

Output

  

다음 코드 예제에서는 값 클래스의 멤버와 대리자를 연결 하는 방법을 보여 줍니다.

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

Output

  

대리자를 구성 하는 방법

사용할 수는 "-" 연산자 구성 된 대리자에서 구성 요소 대리자를 제거할 수 있습니다.

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

Output

  
  
  
  
  

대리자에 전달할 ^ 함수 포인터를 필요로 하는 네이티브 함수

관리 되는 구성 요소에서 네이티브 함수를 관리 되는 구성 요소의 대리자 멤버 함수 다음 호출할 수 포인터 매개 변수 함수의 네이티브 함수를 호출할 수 있습니다.

이 샘플에서는 네이티브 함수를 내보냅니다.dll을 만듭니다.

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

다음 샘플에서는.dll을 사용 하 고 대리자에 대 한 핸들을 함수 포인터를 필요로 하는 네이티브 함수에 전달 합니다.

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

Output

  

관리 되지 않는 함수에 대리자를 연결

네이티브 함수에 대리자를 연결 하는 관리 되는 형식에서 네이티브 함수를 래핑해야 및 통해 호출 하는 함수를 선언 합니다. 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;
}

Output

  

바인딩되지 않은 대리자를 사용 합니다.

바인딩되지 않은 대리자를 사용 하면 함수 대리자가 호출 될 때 호출 하려는 형식의 인스턴스를 전달 수 있습니다.

바인딩되지 않은 대리자는 컬렉션에 있는 개체를 반복 하려는 경우에 특히 유용-를 사용 하 여 각에 대해의 키워드-각 인스턴스에 대해 멤버 함수를 호출 합니다.

하려면 선언, 인스턴스화 및 호출 바인딩되고 대리자 바인딩 해제:

작업

대리자 연결

바인딩되지 않은 대리자

Declare

대리자 시그니처가 대리자를 통해 호출 하려는 함수의 시그니처를 일치 해야 합니다.

대리자 시그니처에 첫 번째 매개 변수 형식이 this 호출 하려는 개체에 대 한.

첫 번째 매개 변수 다음 대리자 시그니처가 대리자를 통해 호출 하려는 함수의 시그니처를 일치 해야 합니다.

인스턴스화할

바인딩된 대리자를 인스턴스화하면 인스턴스 함수, 또는 전역 또는 정적 멤버 함수를 지정할 수 있습니다.

인스턴스 함수에 지정 하려면 멤버 함수를 호출 하는 형식의 인스턴스를 첫 번째 매개 변수 이며 두 번째 매개 변수는 호출 하려는 함수의 주소입니다.

방금 전역 또는 정적 멤버 함수를 호출 하려면 정적 멤버 함수의 이름 또는 전역 함수의 이름을 전달 합니다.

바인딩되지 않은 대리자를 인스턴스화하는 경우 호출 하려는 함수의 주소를 전달 하기만 하면 됩니다.

Call

바인딩된 대리자를 호출할 때 대리자 서명을 하는 데 필요한 매개 변수를 전달 하기만 하면 됩니다.

바인딩된 동일한 대리자를 있지만 첫째 매개 변수로 호출 하려는 함수를 포함 하는 개체의 인스턴스를 포함 해야 합니다.

이 샘플에는 선언, 인스턴스화 및 바인딩되지 않은 대리자를 호출 하는 방법을 보여 줍니다.

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

Output

  

다음 샘플에서는 바인딩되지 않은 대리자를 사용 하는 방법을 보여 줍니다 및 각에 대해의 키워드 컬렉션 개체를 통해 반복 하 고 각 인스턴스에 대해 멤버 함수를 호출 합니다.

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

이 샘플에서는 바인딩되지 않은 대리자를 속성의 접근자 함수를 만듭니다.

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

Output

  

다음 샘플에서는 인스턴스 하나를 연결 하 고 인스턴스가 바인딩되어 있는 멀티 캐스트 대리자를 호출 하는 방법을 보여 줍니다.

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

Output

  

다음 샘플에서는 만들고 바인딩되지 않은 제네릭 대리자를 호출 하는 방법을 보여 줍니다.

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

Output

  

참고 항목

참조

delegate(C++ 구성 요소 확장)