Passing an address of a function

tommyf

Newcomer
Joined
Apr 1, 2004
Messages
21
Hi

Hope somebody can help me.

I am using a 3rd part unmanaged C++ DLL to be able to drag information from an epos system. most of the information I can pull over fine. The problem I have is trying to get the live Electronic Journal information. When I memeber of staff sells something it should automatically post back the information.

This is the documentation that comes with the DLL

short ICR_COMMJob( short TargetECR, short JobNo, short * FileNumberList,
short * FromRecord, short * ToRecord, char * TextData)

Parameters
short TargetECR-Terminal to communicate with. 0 will cause it to use the terminal number as specified in the .ini file 2000 will communicate will all terminals. Communications will go through the terminal number specified in the .ini file.

short JobNo-Job number to run.

Short * FileNumberList-NULL terminated array of file numbers to be processed with the job numbers.

short * FromRecord-NULL terminated array of from record numbers to be processed on the above file numbers. Must be the same length as the file number array. Can be NULL, in which case all from records will be zero.

short * ToRecord-NULL terminated array of to record numbers to be processed on the above file numbers Must be the same length as the file number array. Can be NULL, in which case all to records will be ALL RECORDS.

char * TextData-NULL terminated string, Text data to be sent, used with text message, modem init, modem dial etc

Job 10, Journal Broadcast;
Calling ICR_COMM with job 10 initiates journal broadcast, The address of a function must be passed using the TextData parameter. This function is then called each time journal data is received by ICR_COMM.

Function prototype passed to ICR_COMMJob, must be;

void JournalLineReceived(char szJournalData[48], short sFromECR);

char szJournalData[48] Will contain a NULL terminated string of the data received.

short sFromECR The terminal number of the machine that the data is received from.
Job 10 can be called multiple times for multiple ECRs.

I am trying to run Job 10 as follows

<DllImport("icrcomm.dll", CharSet:=CharSet.Ansi, SetLastError:=True)> _
Private Shared Function ICR_COMMJob(ByVal TargetECR As Short, ByVal JobNo As Short, ByVal FileNumberList() As Short, ByVal FromRecord() As Short, ByVal ToRecord() As Short, ByVal TextData As Object) As Short
End Function

Public Delegate Function ejPassdata(ByVal szJournalData As String, ByVal sFromECR As Char)

Private mydelegate As New ejPassdata(AddressOf JournalLineReceived)

Private Sub ICRCOMMJobEJF()
Dim ret As Short
Dim FileList As Short() = New Short() {900, 0}

ICR_COMMShow()
ICR_COMMJob(101, 10, FileList, Nothing, Nothing, mydelegate)
End Sub

Public Function JournalLineReceived(ByVal szJournalData As String, ByVal sFromECR As Char)
Stop
Me.TextBox1.Text = Me.TextBox1.Text & sFromECR
Me.TextBox1.Text = Me.TextBox1.Text & szJournalData
Me.TextBox1.Refresh()
End Function

So when I click a button it calls ICRCOMMJobEJF() and send the command to the workstation to start posting back data to a text box.

When I run the ICRCOMMJobEJF() everything seems to work ok except when the till is used and it trys to send data back I get a VSHost has stopped working.

I presume I presume my code is wrong and is not pointing back to the correct Function.

Any help would be appriciated
 
Hi I have managed to get a bit further with this. I have managed to pass in the function pointer but get the follwoing error

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

My code is as follows

<DllImport("icrcomm.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Sub ICR_COMMJob(ByVal TargetECR As Short, ByVal JobNo As Short, ByVal FileNumberList() As Short, ByVal FromRecord() As Short, ByVal ToRecord() As Short, ByVal TextData As mycallback)
End Sub

<UnmanagedFunctionPointer(CallingConvention.Cdecl)> _
Public Delegate Sub mycallback(ByRef szJournalData As Byte(), ByVal sFromECR As Integer)


Private Sub ICRCOMMJobEJF()
Dim ret As Short
Dim FileList As Short() = New Short() {900, 0}
Dim del As New mycallback(AddressOf CALLBACK_FUNCTION)

ICR_COMMShow()
ICR_COMMJob(101, 10, FileList, Nothing, Nothing, del)

End Sub

I presume I must be passing the function in wrong somehow.

can somebody tell me how to pass in a callback from an unmanaged dll

Thanks
 
Hi Thank you so very much for your help on this.

It does not actualy highlight the row that is causing the error.

When Private Sub ICRCOMMJobEJF() runs it runs fine with out error. It is only when I hit a button in the till that the error is thrown.


my callback function looks as follows

Public Sub CALLBACK_FUNCTION(ByRef szJournalData As Byte(), ByRef sFromECR As Integer)
Stop
'Code to show reading from till
End Sub

Thanks again
 
It could be the calling convention is wrong and corrupting the stack, equally you might want to force marshalling the strings as ansi - unicode strings could be causing memory to be corrupted if the dll is only expecting ansi.
 
Hi Thank you for your help.

I have managed to get this to work at last.

The only problem i have is that it only callsback once and not everytime the till is used. I think it must be getting garbbaged collected. How do i stop this?


The only other problem I have is that my call back so I have been told should bring back a 48 element char [byte] array. At the moment my call back is

ByVal szJournalData() As Byte and convert this as follows

str = System.Text.Encoding.ASCII.GetString(szJournalData, 0, szJournalData.Length)

But it only brings back one character

Thanks again
 
Is the function supposed to be returning ASCII text? Can you see the contents of the byte array in the debugger - if so does it look like it is only returnin a single byte?
 
Back
Top