Web Interfaces for C++ Introspection?
Milo_Mindbender asks: "For a C++ application I'm working on I want to be able to pop up an interface to a class that will display all the 'tunable' parameters of the class and let me inspect/modify them, while the program is running. The catch is that I'm running on a minimal embedded OS with Open GL but no GUI library. Rather than porting a widget set or writing my own, I was thinking about having the application talk to a web browser, and then use the browser to display the GUI, take user input, and finally push the data back to the app. The classes have metadata that describes the public data locations/types so they can be accessed, but not being a web-wizard I'm not sure of the best way of generating the information I need to create the UI. My first thought is to generate HTML and push that to the browser, but it seems like there must be a better way than this, maybe someone has written a library specifically for doing this sort of thing? Any help/suggestions would be appreciated!"
Any particular reason that it has to be a GUI? Something like an ncurses interface might be a lit easier.
I find this question somewhat odd... The guy clearly knows C++ and is able to develop on an embedded OS which isn't an easy thing to do but yet can't write himself a simple web-server, which a lot of us learnt during our first few years of programming in something nooby like VBA or Java...
So either he isn't being completely accurate in so much that he might not be as knowledgeable as he claims or just by freak chance managed never to write a web-server in a couple of hours like everyone else...
If it must be accessible via the web/intranet/browser/etc, set up some of your favorite CGI/PHP/JSP/Python/Ruby and have it talk to the application via TCP/IP and to the browser with HTTP.
The World Wide Web is dying. Soon, we shall have only the Internet.
Well, C++ doesn't have any metadata on its own, so you must be using something third-party to create it. Since any library that provides the functionality you need will read that data, we need to know what it is!
Of course, I don't know of any such libraries, but anyway. I am very interested in how you'd be doing reflection-type stuff in C++. I'd like to investigate doing that to do mock objects, like nmock does.
You may be interested in XUL then. Especially, in remote XUL.
Also, see Remote XUL Application Development with_Mozilla I and Remote XUL Application Development with Mozilla II.
You may even be able to create the UI XML files automatically from your interfaces, using a script, or introspection.
You can then send the data back to your host, using RPCs or a REST-like interface.
Windows is like decaf - it tastes like the real thing, but it won't get you through the day.
You might consider a very minimal XML interface on top of a very very very simple HTTP server. Your UI could live on a completely different device on a completely different server... or on the same server in a different application stack. You could run your service on port 8080 or something if you didn't want to run it on 80 to prevent
You could display your state as a single XML document that is gotten at a single URL. Each setting could be manipulated by posting to a URL specified in the XML document. These sets of documents and post URLs could become a simple CGI set of interfaces you could describe for anything from webservers, application servers, or other web-aware C++ programs to hook into.
[signature]
HTTP is hardly a very big standard. A few header fields (which he could even ignore for his application), and that's it.
Have you looked at GLUI?
Powered by Web3.5 RC 2
So yeah, write a text interface to a socket, and telnet to it from off the box. It may not be clickably pretty, but he can probably solve his problems quickly. It's what I used to do twelve years ago when I had a similar situation, and it worked just fine then.
John
It would help if you said what the OS was, or at least specified what APIs were available natively. I would suggest that you should not discount the option of using X11 instead of a browser, at least not without evaluating the pros and cons.
Assuming only a socket API, the easiest thing to do is use a simple text-based protocol, talking to a minimalistic TCP server, probably written in PHP, Perl, or Java, and acting as a FastCGI script. You'll find it much quicker and less error prone, chatty, and code-heavy than any markup-based protocol. It's so trivial that it's not rational to even consider any sort of higher-level helper API, I think.
-I like my women like I like my tea: green-
PS. Good alternative to CORBA is ICE (http://www.zeroc.com/ice.html), which is basically the same thing as CORBA, and founded by one of the CORBA gurus. ICE has much better C++ mapping, and lots of other nice features.
Hope this helps!
if you are doing openGL stuff how about throwing in an interactive debug mode. I am pretty sure openGL can sned lines of text in and out just have the app load a translucent console window when launched with --debug
Snowden and Manning are heroes.
I had a similiar problem with how to write a nice GUI in Perl and have an application that can run over a network? I used a webserver and CGI.pm. I don't know whether there are CGI.pm-like libraries for C++, though...
Instead of:
Webapp Your App
Consider:
Webapp Database Your App
Now you have 2 simpler problems: get your app to get its data from a database, and get your webapp to display and modify values in the database.
If he still wants to do the web interface, I'd probably still go the basic TCP/UDP/whatever route, and then have a seperate small web server that that translates between the simple interface and HTTP.
That way you can keep the HTTP/UI code seperate and isolated. Less hair in your core code is a good thing.
Use Qt and declare your tunable parameters as properties. Writing a minimal server using Qt is trivial.
At a place I contract, we do exactly the sort of thing that you want to do. The steps we take are:
1. Define a base class that describes a schema that can be used to store arbitrary data (effectively keeping location and run time type data well defined)
2. All users classes are defined off this base class. *Data* that is to be made externally visible is created in terms of the data schema
3. *Classes* that are to be made visible are instantiated via a class factory, and pointers to them kept in a hash.
4. A separate thread receives requests to inspect/modify data within a specified class. This thread looks up the class in the hash, and then processes the request. But only data in the schema can be accessed. By requesting the schema details from the object, the browser doesn't have to know ahead of time what it is trying to look at.
5. In our case the comms link is via a propriatary protocol, but the data is sent in XML. (Personally I think that this sucks as we can generate megabytes of data when logging, so the transport efficiency is way down. )
I am sure for the right price we can sell you our secrets. But on the other hand, I have seen the inside of all of this mess and it is *not* pretty.
It's a tiny web server with CGI support. You didn't say anything about your target platform, so it's possible that it's still to large, but it's only about 70KB compiled. It would have to be ported to your OS, of course, but at only 8000 lines of code, that shouldn't be too difficult.
As for what to serve up, in the interest of keeping the code small I would suggest defining a custom XML markup rather than HTML. That way your on-board code doesn't have to generate all of the formatting markup to make it look pretty. Instead, for simple presentations you can probably just use a CSS stylesheet (linked from the device-served XML, but not necessarily provided by the device). For more complex presentation, you can use an XSLT stylesheet (again, linked from the), plus CSS for formatting. For the latter, you'll need an XSLT-capable browser, but Firefox and IE6 both fit the requirements, so that's fairly easy.
Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
I'm not sure if I'm on the same page, but could you create bindings using ruby or python and modify your class attributes using an interactive shell like irb?
Rather than porting a widget set or writing my own, I was thinking about having the application talk to a web browser, and then use the browser to display the GUI, take user input, and finally push the data back to the app.
WARNING: BUZZWORD COMPLIANCE ALERT!!!
Uhh, isn't this exactly what AJAX was invented for? If his "minimal embedded OS with Open GL but no GUI library" had an eency-weency [itsy-bitsy?] little webserver, like thttpd, with some sort of an AJAX extension, then he could interactively push [& pull] all of his shiznat to a web browser that lived on a full-featured client operating system.
PS: If youse guys haven't played with it yet, the W3C DOM is the bomb when it comes to this sort of thang. You can do some stuff with the "childNodes" thingamabob that will make your jaw drop.
PPS: Isn't it a little self-contradictory to utter the phrases "minimal embedded" and "Open GL" in the same breath? Or am I missing something?
PPPS: OpenGL [or even VRML] over AJAX via thttpd - now that would be helluva project for a 40-year-old browncoat living in his Mom's basement...
Use something like libhttpd or thttp to embed a webserver. Using ideas based on REST, design a RPC system (can use XML-RPC or if you're bent on making it a web based frontend, then maybe JSON-RPC) to communicate with the GUI.
How about minimal server-side XML + Client side XSLT?
Requirements:
Now all you have to do is serve the XML and stylesheet, attach the stylesheet to the XML file and watch any XSLT-aware browser do the heavy work of transforming that simple XML into beautiful XHTML (or HTML) for you.
Benefits:
Problems:
Why re-invent the wheel writing C++ UIs and stuff when there is plenty of simpler ways out there.
Assuming you don't have a lot of people looking at the same thing at the same time (e.g. just yourself looking at your objects while developing), the easy way is just to have a simple web app save data in a file and your C++ program to read it. Just flock() the file during either read or write.
// pointer addr // int value, etc.
The web server script can just save it like this and then you sscanf:
0x1234
34
Or by whatever other method you use to serialize and deserialize.
Or, you can have your C++ code do a straight memory dump of an object if your web script can parse it with the padding. You just have to make sure you dump each object referenced -- so if name is a char *, and you want to change it, you change the chars at that addr, not change the addr of name, assuming you have enough space. Using a C++ std string that dynamically resizes complicates things.
See the SEAL Reflex project, the OpenC++ project, the PUMA project(now in AspectC++), Arne Adams' reflection library, and XVF by Kurt Stephens. These all work and provide introspection to some degree. There are other projects like Stroustrup and dos Reis's The Pivot and Vandevoorde's Metacode that may make it into future C++ standards to make it easier to provide good introspection support.
- a.pdf
s /DosReis.pdf
s /2003/n1471.pdf
SEAL Reflex http://seal-reflex.web.cern.ch/seal-reflex/
OpenC++ http://opencxx.sourceforge.net/
AspectC++ http://www.aspectc.org/
Reflection library http://www.arneadams.com/index.html
XVF http://kurtstephens.com/research/paper/xvf_paper/
The Pivot talks http://charm.cs.uiuc.edu/patHPC/slides/stroustrup
http://www-unix.mcs.anl.gov/workshops/DSLOpt/Talk
Metacode talk http://www.open-std.org/JTC1/SC22/WG21/docs/paper
Sorry, I guess I missed a few details about what I was looking for. The main thing I was interested in was some library that would autogenerate the http/xml code necessary to display a variable inspection/modification GUI in a web browser. It would be nice if it was already integrated in a library that also did the minimal web-browser stuff needed to send the page to the browser, fill in the data and then manage getting the data back.
Specifically, each object in the app has metadata describing the class members it wanted to appear on this interface, their names, types, pointers...etc. All this info is used internally by the app for other things like delivering network messages, state saving and such. I'd like a library I could hand this metadata to which would then algorithmicly layout a simple GUI, send it to a browser, possiblly update the data if it changes on the app side, then accept changed values back from the user. The functionality is somewhat similar to a remote debugger, but without execution control and with the target app controlling what the user can see and tweek.
Can't really use curses or X directly because the embedded platform doesn't have them. It has an open GL driver/screen and I want to reserve that for actual app output so the UI for displaying/tweeking data needs to be on some other machine. Yes, I could whip-up a windows/linux network app that would talk to the embedded platform and display the data using a native widget set, but using an (already written) web browser seemed easier.
Forgive me if I'm describing something that sounds stupidly easy to do, I just haven't spent a ton of time coding up web-apps (I mostly do embedded stuff) so I'm not all that familiar with all the web standards and tools for doing forms & such. I could write the minimal http server, it's generating the stuff to serve up that I was more sketchy about.
Milo from Kangaroo Koncepts
- Changing the runtime state (introspection)
- The GUI
First, I'd like to ask how much memory you have available on the embedded system, and how many classes you are planning on using this introspection approach on. Do you have threads or processes on the embedded platform? Does your parameter tuning program have to run on multiple platforms?
If you have enough memory, you may want to embed something like lua, tcl, ruby, guile or python and wrap them in C++, then introspect those classes. I know this sounds like overkill, but it will seperate the dynamically changing classes from the rest of the program. As I'm sure you know, it is a pain to manipulate runtime state in C++. Pain will be eased by using SWIG
Do inherit from a class that has something like read_state() and write_state() in some format you can understand. Check boost - they may have something usable for you.
Also, think about whether it is strictly necessary to modify the various attributes on the fly with custom code. What I mean is, if you have a reload()/init() (better yet, the constructors themselves) method in your classes, you can have your GUI write out what amounts to a config file, and use the same interface to change parameters that you do to initialize the objects. This will help you keep your class invarients better.
Whatever you do, try not to let any of the UI muck get tangled in your embedded app. (For example, having your embedded app spit out html directly). Even if you have to write a seperate program to run on the embedded platform, that would be better than having your app communicate with your control program (be it a browser or native UI) directly. ( Unless your embedded app is already a web server :P )
It will almost certainly help you to use a command-line program (write it in some scripting language to save your time) as the first incarnation of the properties twiddler. Use a simple ascii protocol. This will be easy to convert to html later on. You will be happy to have your command line tool while you are debugging the browser interface.
If you have the ability to run a seperate program that just proxies your simple protocol to the web browser, so much the better. Thttpd is your friend here. It is one of the easiest HTTP servers programs to port to a limited platform.
eg. \n
class: foo
attrib: blarg=jack
attrib: sam=600
\n
A web interface has the following advantages:
- Easy to update/change the code
- Cross platform
If you haven't done any client UI stuff on windows or Linux, believe me, now is not the time to learn MFC or X11 or Qt or GTK+ etc etc. The only app I'd attempt with "native" widgets in that case would be with Tk.
Good luck!
P.S. The efficiency hits of all the above will almost certainly be worth it.
XML is pretty and human readable, but there's a lot of space wasted to make it so - especially for just representing a small structure. A binary markup language would probably be better. For example, two bytes of ASCII would get you the < and one character of an XML tag (even less in Unicode) whereas with a special binary format, you could represent the tag as 1 "start of tag" byte followed by 1 "type of tag" byte. Not pretty and not human readable, but you're proposing having another machine parse it anyway, right? It could save one metric heckuvalotta RAM.
Plus, networking drivers, even minimal ones (be they TCP/IP, NetBIOS, NetBEUI, whatever) plus the drivers to interface with the NIC hardware can be fairly large. If the RAM is limited, and therefore what you're transmitting is small, it would probably be easier just to tether it to the "beefy machine" with a serial cable.
Not pretty, but if space and processing power is truly at such a premium...
DATABASE WOW WOW