다음을 통해 공유


Callback 샘플

이 샘플에서는 함수 포인터를 필요로 하는 관리되지 않는 함수에 대리자를 전달하는 방법을 보여 줍니다. 대리자는 메서드에 대한 참조를 보유할 수 있으며 형식 안전 함수 포인터 또는 콜백 함수와 같은 클래스입니다.

참고참고

호출 내에서 대리자를 사용하는 경우 공용 언어 런타임에서는 호출하는 동안 해당 대리자가 가비지 수집되지 않도록 보호합니다.그러나 관리되지 않는 함수에서 호출 완료 후 사용할 대리자를 저장하는 경우에는 관리되지 않는 함수에서 대리자 사용을 마칠 때까지 사용자가 직접 가비지 수집을 방지해야 합니다.자세한 내용은 HandleRef 샘플GCHandle 샘플을 참조하십시오.

Callback 샘플에서는 다음의 관리되지 않는 함수를 사용합니다. 이 함수들은 원래의 함수 선언과 함께 표시되어 있습니다.

  • PinvokeLib.dll에서 내보낸 TestCallBack

    void TestCallBack(FPTR pf, int value);
    
  • PinvokeLib.dll에서 내보낸 TestCallBack2

    void TestCallBack2(FPTR2 pf2, char* value);
    

PinvokeLib.dll은 이러한 함수에 대한 구현이 포함된, 관리되지 않는 사용자 지정 라이브러리입니다.

이 샘플에서, LibWrap 클래스에는 TestCallBack 및 TestCallBack2 메서드에 대한 관리되는 프로토타입이 포함되어 있습니다. 두 메서드 모두 콜백 함수에 대리자를 매개 변수로 전달합니다. 대리자의 시그니처는 해당 대리자가 참조하는 메서드의 시그니처와 일치해야 합니다. 예를 들어, FPtr 및 FPtr2 대리자에는 DoSomething 및 DoSomething2 메서드와 동일한 시그니처가 있습니다.

프로토타입 선언


Public Delegate Function FPtr( ByVal value As Integer ) As Boolean
Public Delegate Function FPtr2( ByVal value As String[]) As Boolean

Public Class LibWrap
    ' Declares managed prototypes for unmanaged functions.
    Declare Sub TestCallBack Lib "..\LIB\PinvokeLib.dll" ( ByVal cb _
        As FPtr, ByVal value As Integer )

    Declare Sub TestCallBack2 Lib "..\LIB\PinvokeLib.dll" ( ByVal cb2 _
        As FPtr2, ByVal value As String[])
End Class
public delegate bool FPtr(int value);
public delegate bool FPtr2(string value);

public class LibWrap
{
    // Declares managed prototypes for unmanaged functions.
    [DllImport("..\\LIB\\PinvokeLib.dll")]
    public static extern void TestCallBack(FPtr cb, int value);

    [DllImport("..\\LIB\\PinvokeLib.dll")]
    public static extern void TestCallBack2(FPtr2 cb2, String value);
}
public delegate bool FPtr(int value);
public delegate bool FPtr2(String^ value);

public ref class LibWrap
{
public:
    // Declares managed prototypes for unmanaged functions.
    [DllImport("..\\LIB\\PinvokeLib.dll")]
    static void TestCallBack(FPtr^ cb, int value);

    [DllImport("..\\LIB\\PinvokeLib.dll")]
    static void TestCallBack2(FPtr2^ cb2, String^ value);
};

함수 호출

Public Class App
   Public Shared Sub Main()
        Dim cb As FPtr
        cb = AddressOf App.DoSomething
        Dim cb2 As FPtr2
        cb2 = AddressOf App.DoSomething2
        LibWrap.TestCallBack( cb, 99 )
        LibWrap.TestCallBack2( cb2, "abc" )
    End Sub 'Main

    Public Shared Function DoSomething( ByVal value As Integer ) As Boolean
        Console.WriteLine( ControlChars.CrLf + "Callback called with param: {0}", value )
        ' ...
        Return True
    End Function

    Public Shared Function DoSomething2( ByVal value As String[]) As Boolean
        Console.WriteLine( ControlChars.CrLf + "Callback called with param: {0}", value )
        ' ...
        Return True
    End Function
End Class
public class App
{
    public static void Main()
    {
        FPtr cb = new FPtr(App.DoSomething);
        LibWrap.TestCallBack(cb, 99);
        FPtr2 cb2 = new FPtr2(App.DoSomething2);
        LibWrap.TestCallBack2(cb2, "abc");
    }

    public static bool DoSomething(int value)
    {
        Console.WriteLine("\nCallback called with param: {0}", value);
        // ...
        return true;
    }

    public static bool DoSomething2( String value )
    {
        Console.WriteLine("\nCallback called with param: {0}", value);
        // ...
        return true;
    }
}
public ref class App
{
public:
    static void Main()
    {
        FPtr^ cb = gcnew FPtr(&App::DoSomething);
        LibWrap::TestCallBack(cb, 99);
        FPtr2^ cb2 = gcnew FPtr2(&App::DoSomething2);
        LibWrap::TestCallBack2(cb2, "abc");
    }

    static bool DoSomething(int value)
    {
        Console::WriteLine("\nCallback called with param: {0}", value);
        // ...
        return true;
    }

    static bool DoSomething2(String^ value)
    {
        Console::WriteLine("\nCallback called with param: {0}", value);
        // ...
        return true;
    }
};

참고 항목

개념

기타 마샬링 샘플

플랫폼 호출 데이터 형식

관리 코드에서 프로토타입 만들기