I want to have several processes running on the same PC that export interfaces that they can use to interact with each other. In the old days on Unix, I would have just written this up from scratch using sockets. I know there must be a more elegant way these days. Is it .com? Active-X, … How about if I want to have something that is portable between Windows and Linux?
That’s a little ambiguous in this context, because “exporting interfaces” has a couple of possible meanings. Can you expand on that without giving away trade secrets?
Unfortunately, the mention of sockets has me thinking of ways to solve the problem using sockets, which makes me think of things where sockets would be the best answer, so I’m of no help. I can think of little that would be portable between Linux and Windows that wouldn’t be socket based, though.
You could still just use sockets; especially if you want it to be cross-platform compatible.
Be a little careful – the Windows implementation of sockets adds a number of useful but non-standard routines, which won’t work when you try to recompile the code to Unix/Linux.
I do socket stuff all the time to let Mac, Windows, and Linux code talk to each other. But then, I’m in southern Oregon, things might be different way up north, there.
I’m looking for the moral equivalent of RPC.
DCOM, maybe. There’s a book by MS Press about it (the title alludes me; something like “DCOM and RPC”, or “COM and RPC”. Also, I haven’t read it). Googling for RPC DCOM gives lots of security advisories, which isn’t the most reassuring thing ever. I’d use sockets, but there is every chance I’m showing my age.
Have you considered using a single multithreaded process? Easy interaction with low I/O overhead, since all of the threads are running with the same data space. There’s a POSIX standard, so it should be portable.
Poratable to everything except MS that is.
You could write a network service, that’s the hot way of doing things these days. The problem is, intergrating non-MS systems into the network. Hey I know, just base everything on MS. Right Bill? :dubious:
Oops, that’s true. Windows does have threads, but they’re not POSIX (unless you’re developing under Cygwin or some other Unixlike emulation layer; I haven’t tried threading anything under Cygwin though).
If you want it to be portable between Windows and Linux, use sockets.
If you’re mainly concerned with making it work on a single Windows system, you can use COM (doesn’t have to be DCOM). Exactly how you do this, and how much work it’ll be, depends on what you’re using for development, but I’ve done it to make two Delphi apps communicate with each other and it was mostly pretty easy.
The basic idea behind using COM for this is that you design an interface that your exposed objects will support, which is just a list of method signatures, like an interface in Java or an abstract base class in C++ (except there are 3 standard methods it must include, for reference counting and conversion between interface types). You assign a GUID to each interface, a 128 bit number that uniquely identifies the interface. Once you have your classes supporting those interfaces, you write a factory class to create instances of the ones you want to expose, and register them with COM using a GUID (known here as a CLSID) or a string identifier (an AppID).
Then, your other app can create instances of these objects, using the CLSID or the AppID, and use whatever methods and properties they expose, just as if they were part of the same application. The method calls will be translated to Windows messages by COM, so both apps will be synchronized, saving you most of the headaches of multithreading (though there are other threading models you can choose too).
ActiveX is basically a set of interfaces and libraries that sit on top of COM. You shouldn’t need to worry about it for this.
.NET also provides a lot of these features in a more straightforward way than COM, and you should be able to call from a .NET application running on Windows into a Mono app running on Linux, using .NET’s standard remoting libraries, if you want to do it that way instead of writing your own socket code.
There are some other ways to do interprocess communication on Windows, like DDE or simple Windows messages. To do the latter, you just register a custom message name with Windows, then use SendMessage or PostMessage to send the message to your other app (after finding its window handle with FindWindow or something). You’re limited to just a couple 32 bit parameters, though, so you’ll need to allocate global memory blocks and send pointers if you want to pass any complicated data around.
If your using .NET and want to go all high powered, XML-RPC and SOAP-RPC can do it.
I use Java RMI (remote method invocation) on Windows. An RMI application can expose an API just like you’d do with COM, but it’s accessible from both local and remote machines and platform independent.
I second the recommendation of XML-RPC or SOAP if you need something higher level than sockets. They’re the standards for web services and other high-level communications these days.
At this level I might give up on trying to get your app to compile on all OSes (unless you’re using Java), and write a simple abstraction layer that would let you use each OS’s handy functions for dealing with this stuff.
If you’re a Perl person, you may want to look into Perl POE.
I think the available mechanisms are:
Windows RPC: don’t know much about it, but it is used internally by a lot of services.
Windows Sockets: you already know about this
Named Pipes: sort of like a socket, just another mechanism to exchange raw binary data between processes. Can ensure authentication.
Shared memory & mutexes, semaphores: if you really want pain
Window messages: your windows app already has a message pump to deal with all the user/system messages that are being sent to it. You can also send/receive custom messages either synchronously or asynchronously and include data through a couple of different buffering mechanisms. We found it to be a clean design for one app because it meant there was only one “entry point” for events, we aren’t blocking or polling. If you don’t care about other events, you don’t need it.
Of course there are languages and frameworks that sit on top of one of these technologies to make them easier to use. .NET Remoting is an example. XML-RPC is another. Essentially they are using sockets. COM is using windows RPC. I imagine CORBA uses sockets as does Java RMI.
If you are stuck using C++ you might only have one framework alternative that is portable, which is CORBA although its likely there are lighter-weight frameworks out there that just aren’t very well-known. If you don’t care about portability then COM is a better alternative to CORBA, especially if you like the idea of reams of template code and IDLs and all that garbage If you have a choice of language and framework then I’d agree with others who recommend .NET Remoting.
The reams of template code and IDLs aren’t really necessary to use COM, although you’d never know it based on looking at 99% of the books or articles out there (the idea that you should protect yourself from the gory details with wads of code you don’t understand seems common). Rare is the book that goes beyond “All you have to do is inherit from CComPlicatedTemplateClass and you’re done!” I recently went through the exercise of implementing a dual interface without ATL, and in my research I ran across this page, which is basically what you’d get if you took every COM tutorial in the world and stripped out the friendly parts. In other words, a good list of how-to samples with little to no explanation. Very dense, but a nice crib sheet for those less-used COM concepts.
I don’t know, seems to me COM is like smashing a fly with a sledgehammer. Why in the world is all that unnecessary complication needed? It appears to be a Tower of Babel to me, as do most MS interfaces.
Well, I don’t want to turn this into a pro-COM/anti-COM debate (especially since DCOM is inherently unsuitable for the “platform independent” aspect of the OP), but at its root, COM is just a really simple mechanism with a pretty straightforward set of rules about handling interface pointers, which serve to solve countless object lifetime problems. The complicated bits come in when you want to call interfaces in other processes or on other computers, because then you have the nastiness of data marshaling, which is an inherently nasty problem.
My one complaint about COM’s complexity is that you’ve got to choose between “raw function calls to local objects” and “completely generic marshaling which can handle anything”, when sometimes all you want to do is call a remote function that takes simple numeric or string parameters (e.g. I’ve defined my interfaces to be easy to marshal by using simple, straightforward data types, but I’m still forced to wade through a lot of goo in order to make that happen). This scenario could be less painful than it is, although I have at times been grateful for having the hard work of real marshaling forced upon me, since it made it much easier to add more complex stuff to my interfaces. It’s one thing to call a procedure in a different process space and have it do something. It’s another thing entirely to be able to pass a pointer to another object into that process space and have it magically work.
I just wanted to add that I thought COM works kinda neat in an IIS environment (COM+) and objects can be used quite well that way both in standalone windows apps and (web)server contexts. Also, .NET provides simple and elegant threading capabilities even in VB.NET and C#.NET (also real classes and such this time, which is great). And of course you can now build services really easy, which could be a great way to deal with your problem, depending on what it is exactly. If you have data-marshalling issues, I’d recommend a SQL database (you can use the free light-weight version)
However, the lack of runtime debugging does make it a slight bit less RAD than VB 6.0 (just a slight bit though). The resizing functions (anchors) for user interface objects are also a neat option.
Web services apparently work really swell too, but I don’t have any experience with them yet.
Your best option depends a lot on the context of your application.