I’m looking to communicate with another app through a pipe. Anyone got any clues as to where to start?
What platform? I believe that on Mac OS X and Linux, Xojo’s IPC sockets are, in fact, named pipes. No on Windows, though.
That would be typical. I of course want to use Windows. Any other suggestions?
Is this a third-party application that already uses Windows pipes, or are you developing both sides yourself? If you’re doing both yourself in Xojo, use the IPCSocket.
If you need an actual win32 pipe for an existing app, you’ll need to use declares to get one or more pipe handles, and manage them. The good news is, once you have acquired a pipe handle you can use it to construct a BinaryStream.
Thanks Andrew. I’m developing to link with a java desktop app, so stuck with the pipe. And when I go looking for the declares there’s your avatar on the post!
What sort of pipe do you need? Windows has two (that I know of) varieties, named and unnamed. If the other app is designed to accept random pipe connections then it’s likely going to be using named pipes, in which case you’d need to know the name.
For example, getting a BinaryStream for a named pipe:
Declare Function CreateFileW Lib "Kernel32" (name As WString, access As Integer, sharemode As Integer, _ SecAtrribs As Integer, CreateDisp As Integer, flags As Integer, template As Integer) As Integer Const GENERIC_READ = &h80000000 Const GENERIC_WRITE = &h40000000 Const OPEN_EXISTING = 3 Dim pipestream As BinaryStream Dim pipename As String = "MyAppPipeName" Dim hFile As Integer = CreateFileW("\\\\.\\pipe\" + PipeName, GENERIC_READ Or GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0) If hFile > 0 Then PipeStream = New BinaryStream(hFile, BinaryStream.HandleTypeWin32Handle) End If pipestream.Write("Hello, world!")
Thanks again Andrew this looks exactly like what I need, and I do have the pipe name. According to the API I need to both read from & write to the pipe. Perhaps I need to connect to it twice once for read & once for write?
No. The BinaryStream will reflect the readable & writable properties of the underlying pipe handle.
In the above code, I specify
GENERIC_READ Or GENERIC_WRITE to
CreateFileW. If the pipe can’t be opened for both reading and writing, then
CreateFileW fails (
hFile will be <= 0). The above code doesn’t handle such errors.
While I have no use for it now, this looks like something useful to file away for the future… but I am not knowledgeable with declares…
After you close the stream, do you have to dispose of/ Release the handle hFile? If so how?
It sounds sounds like IPC sockets on OSX and linux are not limited to talking to Xojo apps but unfortunately not on Windows , but none of that is not mentioned in teh language reference…
If you’re using a stream to manage the handle, closing the stream will dispose of the handle.
Andrew, thanks heaps for your help. I’ve got my test working well with the other app. I created a Xojo class so I could use it as an asynchronous object. You can get it here. I’ve tried to emulate using a TCP socket so everything is familiar.
Since the OP got what he was after, I think it will be find if I drive the thread slightly off its original topic now. I have a couple of questions concerning the pipes and shared memory:
1- The code posted above by Andrew and Wayne connects to an already existing pipe. I read some related MSDN pages and it seems that “CreateNamedPipeW” is the function that is used to create the pipe. In that function you can specify the number of allowed pipes. Can two processes use more than a pipe to communicate to each other, and if so, will it be faster than when using just one pipe?
BTW, this code will create a pipe, in case anyone is interested:
[code]Declare Function CreateNamedPipeW Lib “Kernel32” (name As WString, OpenMode As Integer, PipeMode As Integer, _
nMaxInstances As Integer, nOutBufferSize As Integer, nInBufferSize As Integer, nDefaultTimeOut As Integer, SecurityAtribs as Integer) As Integer
Const PIPE_ACCESS_DUPLEX = &h00000003
Const PIPE_TYPE_BYTE = &h00000000
hFile =CreateNamedPipe("\\.\pipe" + PipeName, PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE, 1, 4096, 4096, 0, 0)[/code]
2- Does anyone know if using a pipe will be faster for transfering a picture between processes than converting the picture to a memory block and sending it over an IPCSocket?
3- For some time, I have been willing to ask in the forum about the possibility of having two processes (a main Xojo app and a console/helper Xojo app) sharing some memory. According to this Wiki page , the data transfer is faster using shared memory than using a pipe, and in this other page one can find the code needed to do it. In that last link they also warn about the problems of using shared memory. Has anyone experience with shared memory and Xojo? Any suggestion or comment?
Two processes can have any number of pipes between them; I don’t think using more than one will make anything faster, just more complicated.
Probably not. You would still need to convert the picture into a memoryblock before sending over the pipe. In almost all cases, the IPCSocket will be the best tool for IPC between Xojo apps.
It’s certainly possible, but you would need you would need to implement everything yourself. That’s a lot of work for not very much gain, IMHO. It would probably be easier to use the Shell class for helper apps.
Wayne, If you’re still listening, I’d like to know why you set the Hidden attribute in the Constructor of your class? This means that if anyone needs to call Super.Constructor (like if they subclass and create their own Constructor), it won’t autocomplete. Was that intentional?
I guess I didn’t think too much about it. There’s no reason to have it hidden.
Thank you Wayne Golding and Julen Ibbaretxe for your posts here on creating and connecting with pipes. This has been extremely useful for me, and is working nicely.