create a CALLBACK from a C++ regular DLL to a vb.net form

tnorton

Member
Joined
Sep 28, 2007
Messages
19
Programming Experience
1-3
Not sure if this is C++ or VB question or both.
I have a poor knowledge of C++ and have converted a C++ SDK to a regular DLL so I can use it in VB.
In VB I declare each function in the DLL as follows
VB.NET:
Public Declare Function VbAuxChannelConnect1 Lib "IVserial.dll" (ByVal m_hDevice As Integer, ByVal IPAddressSerial As String, ByVal SerialPort As Int16, ByVal Priority As Int16, ByVal Persistance As Boolean) As Boolean
Public Declare Function VbAuxChannelSend1 Lib "IVserial.dll" (ByVal ASCIIStringSerial As String, ByVal SerialPort As Int16, ByVal m_hDevice As Integer) As Boolean
Public Declare Function VbAuxChannelDisconnect1 Lib "IVserial.dll" (ByVal SerialPort As Int16, ByVal m_hDevice As Integer) As Boolean

This particular function sends serial data over a LAN to an Indigo Vision video codec.

In the VbAuxChannelConnect1 there is a call back option to let me know we have received a serial string.

The callback function I used to use in C++ is
VB.NET:
    void CALLBACK AuxChanCallback( void       *pUserParam,
                                               VBAUXTYPE   nType,
                                               void       *pData,
                                               int         nSize ) 
    {
        char szReceivedData[1024];
        char *pszSerialData = (char *)pData;
        
        strncpy( szReceivedData, pszSerialData, nSize );
        szReceivedData[ nSize ] = '\0'; // null terminate this string.

        // print received serial data out
        //printf("Received serial data from Transmitter: %s\n", szReceivedData);
        return;
	}

[COLOR="Blue"]and the exported function [/COLOR]

bool __stdcall VbAuxChannelConnect1(HANDLE m_hDevice,const char *IPAddressSerial, VBAUXTYPE SerialPort, int Priority, bool Persistant)
{
	BOOL m_bStatus;
    m_bStatus=VbAuxChannelConnect(
            m_hDevice,
            IPAddressSerial, // Transmitter IP
            SerialPort,
            Priority, // use a maximum priority for this connection if HW link. Else 1 low - 10 High
            "MyConnection", // a friendly name for this connection
            Persistant, // persist flag, ignored for PC serial connections
            [COLOR="Red"]AuxChanCallback[/COLOR], // callback function which receives serial data from Transmitter
           NULL
			);


How can I make this CALLBACK to me VB forms?
 
A callback in C++ is a function pointer. The .NET equivalent is a delegate. If you need to declare an external function with a function pointer argument you declare it with a delegate argument. You then pass (AddressOf MyFunction) as the parameter.
 
A callback in C++ is a function pointer. The .NET equivalent is a delegate. If you need to declare an external function with a function pointer argument you declare it with a delegate argument. You then pass (AddressOf MyFunction) as the parameter.

I am still not understanding this fully.
I did some searching and think I understand the VB side but to pass a pointer from VB to c++ I need to declare its type.

I found this snippit for the C side but cant get it to work
VB.NET:
// C++/CLI library

public delegate void SampleDelegate(Object^ data);

public ref class SampleClass
{
...
public:
    void SampleFunction(SampleDelegate^ callback)
    {
        String^ s = gcnew String(L"123");

        callback(s);
    }
};


does the SampleDelegate^ or mor specifically ^ mean a pointer? I thought in C++ a *myVariable was a pointer

Can you provide a sample of the VB and c++ sides?
 
That's C++.NET. In C++.NET a pointer is still indicated by a '*'. The '^' indicates a reference. That's equivalent to a normal reference type variable in C# or VB, i.e. any variable that refers to an instance of a class, delegate or some other reference type.
 
After much reserach I have it working.

Thnks for the assistance

VB CODE:
VB.NET:
Public Delegate Sub Callback(ByVal sUserPram As String, ByVal mmm As Int16, ByVal mData As String, ByVal nSize As Int16)


    Private Declare Function VbAuxChannelConnect1 Lib "IVserial.dll" _
        (ByVal m_hDevice As Integer, ByVal IPAddressSerial As String, ByVal SerialPort As Int16, ByVal Priority As Int16, ByVal Persistance As Boolean, ByVal CalBckFunc As Callback) As Boolean


   Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim cb As Callback
        cb = AddressOf CallBackFunc
        Delegate1(cb)
    End Sub
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim n

        n = VbAuxChannelConnect1(m_hDevice, "192.168.1.10", 1, 5, False, AddressOf CallBackFunc)
        MsgBox("VbAuxChannelConnect1 " & n)
    end sub

Private Sub CallBackFunc(ByVal sUserPram As String, ByVal mPort As Int16, ByVal mData As String, ByVal nSize As Int16)

        Dim mstring As String
        mstring = sUserPram & vbCrLf & _
            "Com Port " & mmm & vbCrLf & _
            "Data Rx " & mData & vbCrLf & _
            "Characters Rx " & nSize

        MsgBox("Callback worked" & vbCrLf & mstring)
    End Sub


C CODE:

VB.NET:
bool __stdcall VbAuxChannelConnect1(HANDLE m_hDevice,const char *IPAddressSerial, VBAUXTYPE SerialPort, int Priority, bool Persistant, VBAUXCHANCALLBACK myCallback)
{
	BOOL m_bStatus;
    m_bStatus=VbAuxChannelConnect(
            m_hDevice,
            IPAddressSerial, // Transmitter IP
            SerialPort,
            Priority, // use a maximum priority for this connection if HW link. Else 1 low - 10 High
            "MyConnection", // a friendly name for this connection
            Persistant, // persist flag, ignored for PC serial connections
            myCallback, // callback function which receives serial data from Transmitter
           NULL
			);

	if(!m_bStatus)
		{
			return FALSE;
		}

	return true;
}
 
New problem linked to this call back

The call back works most of the time but occasionally I get this error.
I have tried various changes to fix this but really dont know what I am looking for

CallbackOnCollectedDelegate was detected
Message: A callback was made on a garbage collected delegate of type 'WJRT416 Indigo!WJRT416_Indigo.Nortronics.Indigo.IVcomObjects+SerialCallback::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called.
 
That error message indicates that your delegate has been cleaned up by the garbage collector and then an attempt has been made to invoke it again. The problem is that you are creating your delegate, and only assigning it to a local variable. That local variable falls out of scope as soon as the method it's declared in completes. That means that there are no more managed references to that delegate object so it becomes available for garbage collection. When it gets cleaned up by the garbage collector is indeterminate, so it will not fail some of the time. You need to assign your delegate to a variable that doesn't lose scope to ensure that it doesn't get cleaned up, so it is guaranteed to be accessible when it is invoked by the unmanaged code.
 
Back
Top