ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I am writing a gui using gtk and C++. This leads to an obvious need to pass object and class references to functions. Given that gtk is completely driven by its own internal signal mechanism, the obvious way to pass these class references is by putting a pointer to them in the GObject structure,which is the basic structure for all gtk widgets.
Alternatively, I have to define my objects as global so that they can be accessed from wherever, but I want to avoid that if at all possible.
So, I have done this. I have defined a class called drawing_area, which incorporates a lot of functions associated with a drawing area that I am using for graphing. In my main function, I have defined an instance of that class, called da.
I have tried a number of other casting mechanisms as well. All return errors. In the second variant I have shown here the error is:
Quote:
commander.cc: In function 'void begin_collect_data(GtkObject*)':
commander.cc:92: error: invalid cast from type 'void*' to type 'drawing_area'
which is really no surprise because I am trying to cast a pointer to a non-pointer.
In the first variant I show here, the message is:
Quote:
commander.cc:93: error: request for member 'get_drawing_area_size' in 'db', which is of non-class type 'drawing_area*'
commander.cc:99: error: request for member 'draw_rectangle' in 'db', which is of non-class type 'drawing_area*'
What I am trying to do is fairly obvious. Can anyone tell me how to do it?
What I am trying to do is fairly obvious. Can anyone tell me how to do it?
Try something like this
Code:
drawing_area* db = reinterpret_cast<drawing_area *>(g_object_get_data((GObject *)object,"testdata"));
size = db->get_drawing_area_size;
result = db->draw_rectangle(size);
You have to de-reference a pointer using "->". You did not actually pass a reference to the object in the call to "g_object_set_data", but the address of the object (AKA a pointer to the object).
drawing_area* db = reinterpret_cast<drawing_area *>(g_object_get_data((GObject *)object,"testdata"));
size = db->get_drawing_area_size;
result = db->draw_rectangle(size);
You have to de-reference a pointer using "->". You did not actually pass a reference to the object in the call to "g_object_set_data", but the address of the object (AKA a pointer to the object).
D'uh!
I knew that. At least, I should have.
Oh well. Thanks for pointing it out.
I also spent an hour today tracking down a for loop that wasn't working right. That is how long it took me to spot the semicolon at the end of the line.
You should also ask yourself this: Why does a GObject button need access to data? There's rarely a requirement leading to that conclusion than can't be accomplished in a more graceful way, especially with C++. This might just be style and preference, but I think the procedure should own the GUI instead of the GUI owning the procedure. In other words, I find it much easier to maintain GUI/procedure interaction if the GUI is strictly an extension of the procedure and its associated data and logic. In C++, even when mixed with C, there's rarely a case (other than thread instantiation) where you can't avoid circumventing type safety.
You might find it cleaner and simpler to provide a global, C-friendly function to control the action of the button, backed by C++ in a way that appropriately calls the method against the active drawing_area. The button isn't there to be the action, after all; it's there because the button being pressed has meaning to the underlying logic. The GUI doesn't need to know what's going on with the program; it's merely the point of interaction between the user and the underlying system.
Even if it's the sort of program that has multiple windows at a time, and therefore a button3 in several identical GUIs, this can still generally be dealt with in the same way. You'd just need the button to pass some sort of index to the global function.
ta0kira
No worries. We all have our public brain fades. Just read some of my answers to questions and see where I had to edit them later because I was in a rush and left something out.
You should also ask yourself this: Why does a GObject button need access to data?
The button doesn't need access to the data. The routine(s) that are called when the button is clicked need access to the data. But the only way I see to provide this access (unless I provide the access globally, which I really don't want to do) is to pass a pointer with the GObject. I say this because I am building the GUI with glade, and only the GObject and predefined user data is passed by gtk into the signal handler. Since I am using glade, I can't put anything useful into that user data field because the contents of that field are loaded from an xml file at runtime.
I realized after that last post that if one structures a GUI with a parallel data interface (as I do with binary trees,) buttons associated with the corresponding objects will need to know what objects they're attached to in order to propagate their actions. This can obviously apply to your situation. Sorry about that! But (for others,) my philosophy on GUIs stands as posted previously, with this as an exception to keeping GUI components in the dark.
ta0kira
When working with gtk, it seems to me that structuring the GUI in parallel with the data is pretty much required for any but the simplest of GUIs. The architecture of gtk motivates that; it is single threaded and event driven. So it works best if you process the signal quickly, pass off the required data/signals/whatever else to the appropriate routine (in a separate thread if it doesn't run very quickly), then return so that gtk will be able to process the next event. And without the capability to pass objects around, you'd be using a lot of globals. I have seen a lot of complaints that "gtk is slow" but this, it seems to me, is because the architecture of the slow program isn't parallel. My gtk interface is quite responsive, but it is fully parallel. It is also very busy.
In my particular case, I find myself having to have a parallel thread that accesses gtk, along with the thread that handles the gui because I am implementing a spectrum analyzer display that needs to collect data and display it in real time - while still handling other button clicks/mouse tracking, etc. Thus, the gtk gui has a real-time animation running in it and I have to run a separate thread to update that animation. This carried with it some implications that I haven't encountered before with gtk.
It is working now, and I am very pleased with it. Gtk is not limiting my system; network bandwidth is because I am shipping the data that is to be displayed across the network (which could be anything but most commonly will be the internet) at 64KB per sample.
Maybe you should just export the display and limit explicit network traffic to process-control messages. Or pre-process the display data and transfer that over the network. It sounds like the display program doesn't need the data itself; just its analysis. You should be able to do that unless the source machine would be unduly bogged down by processing data for display, then you could make it a subscription-based service where all connected clients receive the next frame as it's processed. The actual display bitmap wouldn't be transferred, nor the raw data; just, e.g. the histogram data pairs, to be rendered for display by the receiver. This would also allow you to export a feed to PNGs, etc.
As far as having a second thread; that's a great idea with lengthy processes. One of the most irritating things as an end user is to initiate a process, only to change one's mind to cancel it, but having the GUI frozen because it's in the same thread as the process.
ta0kira
The machine generating the data is doing real time processing and I want it to run as fast as possible. In fact, the architecture there is such that servicing the spectrum analyzer display on the client is given a low priority and, should the workload get high enough, the client will lose frames. Because of that, I have explicitly refused to do any pre-processing for the display on that box. The data sent to the spectrum analyzer is sent as a straight dump of 4 byte reals, and it is then processed into pixel positions.
The GUI is a command and control program for this real-time system; I need the spectrum analyzer display to see what the system is seeing
Well, since you're still indulging me, have you compared the costs of pre-processing vs. writing millions of bytes to a network port? It sounds like you're at least grouping them, which should minimize (TCP?) frames, but you might find that even a very minor amount of pre-processing could greatly reduce the data transferred, and it might be done in a way that saves both clock cycles on the RT machine (because of reduced network transfer) and bandwidth. While a LAN is fairly reliable, you probably have some level of transmission retry over the internet due to errors.
Another suggestion (as if you can just go redesigning things, etc. ,) more of a question, is that if this machine is so important, why is it directly connected to the internet? It would probably be safer and faster to connect it to some sort of data-analysis machine (some cheap piece of crap) that does nothing but receive data, pre-process it, and forward it over the network. You might even set said piece of crap on top of the other machine and connect them with a serial port or USB. Important people don't deal with other people; they have less important people to do that sort of thing...
ta0kira
LOL. The spectrum analyzer display won't be running all the time - only when an operator needs to look at what the system is seeing either for manual calibration purposes or for diagnostic purposes. I am looking for ways to reduce the amount of data transferred. This project is going to go on for quite awhile; efficiencies may suggest themselves.
I want to ship the actual data and not pixel-processed data because, among other things, we might choose to save this data for further analysis. Just depends.
As for why this guy is connected directly to the internet, it is because he is part of the internet. This guy will be the mother (mixed metaphors...lol) of all wireless routers. He is a satellite communications node, and will be monitoring and switching signals among N satellites and M wired and wireless (data link) data connections, mostly in remote locations of the globe.
I am actually building out the hub of this system, while also designing and implementing some hardware and software that implements a patented protocol that will increase efficiency of satellite bandwidth usage. I'm doing most of the software and integration; an associate and I are doing some custom hardware with a DSP in it, and my client owns and maintains the sites.
Right now, my associate and I are doing the core engineering and physics tasks, including proof of concept. When we are satisfied that this all works - when all the major systems engineering is done (and it almost is done), the project will become a fairly routine software engineering job. At that point, I may hire a team to expedite the development and move into the role of project manager.
The gui lets me look at and control, one at a time, any of a number of different satellite monitoring stations to see what they see and adjust what they look at and how they look at it.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.