David

 

This time, it’s not MapInfo you should be blaming; it is the syntax in .NET interop that you need to get on top of. If you have the MSDN Library, have a look at Pinvoke and COM, and search for Callbacks.

 

There is a very simple example called “Callback Sample” (one place where you can see it is on MSDN2 website, http://msdn2.microsoft.com/en-us/library/5zwkzwf4.aspx) which explains what you need to do.

 

Fortunately for VB6 people, the Declare syntax can be used (the alternative [ DllImport(PathToSomeDLL)] is mandatory for C#, optional for VB.NET). I will paste in the code and article here, for benefit of others who might be tempted to try the .NET way “sometime soon”.

 

Otherwise, it is much the same as you are used to in VB6.

 

IL Thomas
GeoSciSoft  - Perth, Australia


This sample demonstrates how to pass delegates to an unmanaged function expecting function pointers. A delegate is a class that can hold a reference to a method and is equivalent to a type-safe function pointer or a callback function. The Microsoft .NET Framework SDK includes the complete Visual Basic .NET and C# versions of this sample in Samples\Technologies\Interop\Platform-Invoke.

Note   When you use a delegate inside a call, the common language runtime protects the delegate from being garbage collected for the duration of that call. However, if the unmanaged function stores the delegate to use after the call completes, you must manually prevent garbage collection until the unmanaged function finishes with the delegate. For more information, see the HandleRef Sample and GCHandle Sample.

The Callback sample uses the following unmanaged functions, shown with their original function declaration:

  • TestCallBack exported from PinvokeLib.dll.
void TestCallBack(FPTR pf, int value);

  • TestCallBack2 exported from PinvokeLib.dll.
void TestCallBack2(FPTR2 pf2, char* value);

PinvokeLib.dll is a custom unmanaged library that contains an implementation for the previously listed functions.

In this sample, the LibWrap class contains managed prototypes for the TestCallBack and TestCallBack2 methods. Both methods pass a delegate to a callback function as a parameter. The signature of the delegate must match the signature of the method it references. For example, the FPtr and FPtr2 delegates have signatures that are identical to the DoSomething and DoSomething2 methods.

Declaring Prototypes

[Visual Basic]
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 'LibWrap
[C#]
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 );   
}

Calling Functions

[Visual Basic]
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 )
      ...
   End Function 'DoSomething
   Public Shared Function DoSomething2( ByVal value As String ) As Boolean
      Console.WriteLine( ControlChars.CrLf + "Callback called with _
          param: {0}", value )
      ...
   End Function 'DoSomething2
End Class 'App
[C#]
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 );
      ...
   }
   public static bool DoSomething2( String value )
   {
      Console.WriteLine( "\nCallback called with param: {0}", value );
      ...
   }   
}

[ End of code example ]


From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of David Hebblethwaite
Sent: Tuesday, May 30, 2006 2:17 PM
To: mapinfo-l@lists.directionsmag.com
Subject: [MI-L] Callbacks with VB.NET2005

 

I am trying to get an integrated mapping application working with Mapinfo 7.8 and VB.NET2005. I have created similar applications before with VB6 and MapInfo but I have been unable to get the callback function working with vb.NET. I have created a standard Windows project and a class containing the methods by which MapInfo notifies the calling program. In the main form I create a public instance of the class and call MapInfo's SetCallBack method with the instance as the argument. Although I can quite happily control MapInfo from the VB.NET program I get no response at all from actions in the MapInfo window. I have tried to implement some of the ideas that have appeared in MI-L but with no success.  I know I am not the only one with this problem. Does anyone know of any rules/steps that will lead to a successful implementation of the callback function? I find it hard to believe that MapInfo would provide this method without some clear-cut way of implementing it. Any advice would be appreciated.

 

David Hebblethwaite

 

_______________________________________________
MapInfo-L mailing list
MapInfo-L@lists.directionsmag.com
http://www.directionsmag.com/mailman/listinfo/mapinfo-l

Reply via email to