Socket Callback into Vb

Started by DavMin, December 12, 2011, 09:59:00 AM

Previous topic - Next topic

DavMin

I'd like to use net-listen to signal a data received event into my Vb application. I'm using the newlisp.dll and didn't want to poll the port. Is this possible?



Thanks.

DavMin

#1
I should mention this is Vba/Vb6, not .net



Thanks.

sunmountain

#2
Anything is possible.

Perhaps you could just outline the idea a bit more or send some (pseudo) code ?

DavMin

#3
Oh, ok.



In Vb, when I add a reference to a DLL I can see the interfaces in the object viewer. If I add newlisp.dll there is one function: NewlispEval.



Some DLL have events that can be hooked within the editor. A fictional socket interface would have a DataReceived event:


Private Sub Socket1_DataReceived()
Me.Text1 = Socket1.IncomingData
End Sub


I've read that newlisp handles a set number of callbacks. I imagined that each callback could be set through the NewlispEval function then have generic event handles for those callbacks:


Private Sub NewLisp_Callback1()
Me.Text1 = NewLispEval("(net-receive socket 'buf 1)")
End Sub


 Sorry, not very good at sockets or newlisp yet. I've played around with sockets in vb months ago and found it terribly difficult. There was a 'DataReceived' event but what I actually wanted was an asynchronous "Data Complete" so I could let the form work as usual and show asynchronous updates as they come.



Thanks

sunmountain

#4
To get you right:

you want to handle all network stuff with newlisp and have it inform the VB app an changed data ?



Anyway:

net-listen sets up a listening socket, essentially flagging the socket to be a server socket.

Then, you have to net-accept on the socket, to catch new incoming requests.

Normally, this operation blocks until new clients connect.

You then get a new client, on which you operate (net-receive, net-send).

On Unix you could use net-select et al to implement non-blocking sockets even with unblock net-accept.

That said: If you set up newlisp to wait for events, your form will do nothing - except you

do that in a thread - which complicates the thing even more.



The easiest thing for you would be to: take VB.NET (Express or SharpDevelop will do) and go with

.NET - all is solved there.

Or take  newlisp and create the form with gui server, or take newlisp and interface some UI lib like gtk or iup.

Lutz

#5
Some comments about networking in newLISP:



net-select also works on Windows, as does net-peek. Both can be used to implement non-blocking communications on both, Unix and Windows OSs.



Make sure you also read the relevant chapters about network communications in:



http://www.newlisp.org/downloads/CodePatterns.html">http://www.newlisp.org/downloads/CodePatterns.html



Who most has pushed and tested TCP/IP and UDP networking in newLISP to the limits is Norman from:



http://newlisp.digidep.net">http://newlisp.digidep.net



Some code of his may not have been updated to the 10.0 and after generations of newLISP, but little has changed in networking since before 10.0.

DavMin

#6
Quote from: "sunmountain"To get you right:

you want to handle all network stuff with newlisp and have it inform the VB app an changed data ?

--

That said: If you set up newlisp to wait for events, your form will do nothing - except you

do that in a thread - which complicates the thing even more.


Example: I use an Internet Explorer control and load a web page

webbrowser0.navigate "asd.com"



The form doesn't block or wait in a loop, it responds to commands.

After the web page is downloaded a webbrowser0.downloadcomplete event fires and I can write code to respond.



I guess I'm just asking if you can register callbacks to respond through the DLL and allow the DLL to operate asynchronously.



Using .net just complicates things even more for me. My only other idea would be to use the odbc connection to write messages to a shared table and use a timer to periodically query.

sunmountain

#7
QuoteThe form doesn't block or wait in a loop, it responds to commands.

After the web page is downloaded a webbrowser0.downloadcomplete event fires and I can write code to respond.


So the problem is solved ?

I still think it is not more complex in .NET/C#:



using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WebCrawlerWithNewLisp
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
[DllImport("newlisp.dll", EntryPoint="newlispEvalStr",CharSet = CharSet.Ansi)]

public extern static string newlispEvalStr(string cmd);

public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();

//
// TODO: Add constructor code after the InitializeComponent() call.
//

}

void Button1Click(object sender, EventArgs e)
{
webBrowser1.Url = new System.Uri(textBox1.Text);
webBrowser1.Update();
}

void WebBrowser1DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// this will be called on completion !
MessageBox.Show(newlispEvalStr(@"(println ""Hello from Newlisp - embedded in C# !"")"),"Loading completed");

}
}
}


The VB.NET code would look really a lot like this.

DavMin

#8
I think you are missing my point. I was using the Webbrowser.DownloadComplete event as example of an asynchronous event.



I can load and call the newlisp.dll all I want and it works and I am happy with that. What I was wondering was if it's possible to assign newlisp.dll a callback:



Sub Form_Open()

Newlisp "(load 'socket.lsp')"

Newlisp.Callback("Socket_DataComplete")

End Sub



Sub Socket_DataComplete(IncomingData as String)

Me.Text1 = IncomingData

End Sub



Where Newlisp.Callback is assigned the function or subroutine to call when socket.lsp has completed processing of a new message.

Lutz

#9
Perhaps you mean this:



http://www.newlisp.org/code/callback-from-newlisp-lib.txt">http://www.newlisp.org/code/callback-fr ... sp-lib.txt">http://www.newlisp.org/code/callback-from-newlisp-lib.txt



http://www.newlisp.org/syntax.cgi?code/callback-from-newlisp-lib.txt">http://www.newlisp.org/syntax.cgi?code/ ... sp-lib.txt">http://www.newlisp.org/syntax.cgi?code/callback-from-newlisp-lib.txt   <- with syntax highlighting



here demoed with newlisp registering a callback in newlisp.dll

DavMin

#10
Yes, I think that's what I need and I saw this code in the manual earlier.. but I still don't understand how I'd hook this up in my code.



I have:



Public Declare Function NewlispEval Lib "NewLisp" Alias "newlispEvalStr" (ByVal LExpr As String) As Long



so I would also declare:



Public Declare Function NewlispCallback Lib "NewLisp" Alias "newlispCallback" (ByVal Callback As String) As Long



?



Then in my code I would write:



Sub Form_Open()

NewlispEval "(load callme.lsp)"

NewlispCallback "CallbackHandler"

End Sub



Sub CallbackHandler(DataReturned as String)

Text1 = DataReturned

End Sub



?



I think I'm missing something. What is initially returned by NewlispCallback ? Probably not a long, maybe a boolean for success/fail? Then what is returned by the callback itself? A string? A pointer to a string?



This is the code I got from the Excel example:


Function NewLisp(LispExpression As String) As Variant
    Dim Result As String
    Dim ResHandle As Long
    Dim ResultCode As Long
    ResHandle = dllNewlispEval(LispExpression)
    Result = Space$(lstrLen(ByVal ResHandle))
    lstrCpy ByVal Result, ByVal ResHandle
    NewLisp = Result
End Function


I mention this because there is some post processing of the returned pointer. Is the value returned by the callback a pointer as well?



Thanks!

DavMin

#11
Ok, wait. I think I see what's going on.



The example you are giving is how to register a callback in the dll from lisp.



What I am wanting to do is register a callback in the dll from Vba/Vb6.



So there is a hook in the dll to register a callback but there seems to be no way to callback into Vb because it's using a different namespace for it's functions.



However, I have seen this done before in a com/dll. I think it's possible, I'm just not as knowledgeable as you folks here.



Thanks

DavMin

#12
A different option would be to run newlisp.exe with the socket code loaded and use SendMessage API from within the newlisp program to notify my main program when data is complete.