[noob] get data out of a function to a GUI

Hi members!

[edited, sorry, mistake in 1st version of text ;) ]

My question is sure kind of noobish, because I want to start to develop my programming skills. I chose linux/qt as a base. But my question is more a common one:

I've got code in an existing more or less big library (*.c and *.h) and I want to get the output away from this library and have it in my gui. So the problem is, that in the library are many "printf" or even "cout".
Now I dont want to directly redirect the whole output, I want to get the strings and other data to my routine, which itself works this up and send it to the gui.
It is no problem to change the code in the library.
My Problem is in logic: how have I to implement it?! The library knows nothing from the routine in my gui-program.

My starting point is the following:

gui.h
1
2
3
4
5
#include <whatever>

void writeDataFromLibtoGUI(QString datafromlib);
void getIntFromLibtoGui(int dataFromLib);
....


Problem is in between ^^ vv

library.h
1
2
3
4
5
#include <whatever>

void processdata1(const char *string, int i);
void processdata2(int k);
....


library.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <whatever>

void processdata1(const char *string, int i){
...
    printf("Data: %d",i);    //--- this should be realized by writeDataFromLibtoGUI() from GUI
    printf(string);          //--- this should be realized by writeDataFromLibtoGUI() from GUI
...
}

void processdata2(int k){
...
    k=k+123;
    printf("Even more Data: %d",k);    //--- this should be realized by getIntFromLibtoGui() from GUI
...
}


What is the clue to get both things together?! Have I to implement a kind of "interface" between them?

Sorry for that maybe simple question, but as I said - I'm a bloody beginer :)
An please no answers like "dont take qt as a beginer..." or whatsoever
Last edited on
Maybe it looks like an joke like from 1st April - but no, it isn't! Maybe it is to simple?! I did not get it - how is a problem like this to be solved?
And as I stated, I'm a beginner in programming, although I'm working with linux for years! ;)
1. Your library should not have any output statements in the first place (or at least they should be conditionally enabled by the processor if you want to build in Debug mode)
2. You should not mix usage of C I/O (e.g printf) and C++ I/O (e.g std::cout)
3. It is possible to replace the buffer that std::cout uses thanks to the design that the C++ stream library sues, but I don't know about the C I/O library.
to 1.: the problem is, that the library has output statements and in its philosophy there is too much effort to rewrite the whole lib - it is not my lib, it is a given one with some 1000 lines of code.
to 2.: there is not much mixed up - most of all are printf (C only, slightly adapted with changes for C++)
to 3.: okay, i will pay attention to this

But in generally: how should I start, if I want to write a whole new lib which should work mostly independently from a given output routine? It should just calculate something or get some information from elsewhere (e.g. sensors). The results has to be shown elsewhere - maybe in a GUI application on a PC or maybe on a µ-pro driven LED Display. So I guess it should stuck with C not wiht C++.

As I'm not a programmer nor a computer scientist, only electrical engineer without programming experience I have no idea of MVC or what else.
I want just a short description of how to handle that.

So in short: how to realize this way:

 
(lib) int result = routine;  ~> adaptor_routine(int result); ~> (main) QMainWindow->QComboBox->setCurrentIndex(result);
bobc wrote:
to 1.: the problem is, that the library has output statements and in its philosophy there is too much effort to rewrite the whole lib - it is not my lib, it is a given one with some 1000 lines of code.
1
2
3
#ifndef DEBUG
#define printf(...) 0
#endif 
bobc wrote:
But in generally: how should I start, if I want to write a whole new lib which should work mostly independently from a given output routine? It should just calculate something or get some information from elsewhere (e.g. sensors). The results has to be shown elsewhere - maybe in a GUI application on a PC or maybe on a µ-pro driven LED Display. So I guess it should stuck with C not wiht C++.
Generally, a library should only give output in debug mode. A release library should never interfere with a program's output stream (what if the program using the library has their output stream piped somewhere that needs output in a specific format?).

Most libraries I have seen don't even have debug print statements at all, they just get added in whenever they are needed. If you need to communicate something to the code using your library, it should be via a callback.

I'm not sure what you're trying to ask for with your example at he bottom of your post, could you explain it in more detail? I understand you are not a computer scientist, that is fine.
Last edited on
LB: Thanks for so far for answering beginners stupid questions - the problem is to ask the correct question ;)

The short example should visualize the way of any desired data from any kind of library to any kind of frontend and the question was, how to realize this in a good programming manner.


As I wrote, I got never a complete course for learning programming so the whole theory like how things has to be started or how should those things be done I'm not quite familiar with. Straight forward (functional) programming is simple with one big main() and some subroutines. ;) The syntax of C/C++ or even e.g. Delphi is also quite simple, but more important is how to use it in an efficient way. Not necessarily templates or mysteries like this, but maybe the theory of callback functions or the like.

Again: thanks for your time!
I'm still not really understanding what you're trying to get at. Do you want to library to send information to your program without using the return value or do you want the library to continually call one of your functions for clarification on certain things?
Simply I want a library routine to send any value to a gui programm.

But my problem of understanding is: if the lib knows nothing of the data structures of the gui programm AND the library has many *.h and *.c files, how should I connect both of them - especially as the lib has some routines which gave back a status code but not the value itself.
e.g.:
1
2
3
4
5
6
7
int f1(int a,b){
if ((a*b)>0){
  printf(a*b);
  return 1
  }
return 0
}


But I want to show (a*b) in another routine of my gui. The return code is on the other hand important for other function inside the lib, so I cannot simply rewrite the returned value.
But I know, it could be possible to ad an optional parameter to the function like "int f1(int a, int b, long *returnpointer) " - could that be one solution? But in this case I dont know how to make the *returnpointer optional.
Why do you want to do this? It doesn't really make sense; the point of a library is that it can be used by any program or software regardless of how the software works.

Still, though, it would have to be with a callback. Your example is very general so I'm not to clear on the usefulness, but the general idea is that you pass a function pointer.

Example:
1
2
3
4
5
6
7
8
9
10
//library function
int f1(int a, int b, void (*callback)(int atimesb))
{
    if(a*b > 0)
    {
        callback(a*b);
        return 1;
    }
    return 0;
}
1
2
3
4
5
6
7
8
9
10
//your code
void MyCallbackFunctionForF1(int val)
{
    std::cout << "library's f1 says: " << val << std::endl;
}

int main()
{
    f1(1, 2, &MyCallbackFunctionForF1);
}

"...the point of a library is that it can be used by any program or software regardless of how the software works..."

Yes, that is what I understand and it should be working like this. But I did not really know, how do this on a correct - in the sense of a good programming manner - way. (the example of the lib's function is only a short constructed and theoretical one)
The solution with a callback seems to be one thing I could understand ;)
So if I can extend the library in this way that I replace all the "printf" it should work.

But how has the library to be written when it should be completely independent from the calling application? Now the callback is in the main application. Could this callback be moved to the lib and be rewritten so that it is more common and it just only moves the data back and forth? In the form of a "common interface" or the like?

PS: ah, or should a library always set on such a callback mechanism for data-handling? Or are there other ways to import and export data from and to a lib-routine? Maybe kind of pointer a "struct" as a common data structure for data exchange?
Last edited on
The point of a callback is that it is defined outside the library, that's why it is comprised of the words "call" and "back" - the program using the library calls a function of the library, and the library 'calls back' to the program using it to notify it of something or get more information.

You can use these callbacks for whatever purpose you want, or if you want strictly data I/O you could pass streams by reference. The problem with passing more complex C++ objects is that the library and program then have to be compiled the same way, otherwise the internal structure of the classes in the C++ standard library will differ from library to program, and your program will crash. This is why the callback technique is preferred - 99% of the time, even the most different compilers will compile compatible code between the library and the program using it.
Ah, okay. I guess it could be a problem of maybe (long-)int oder float as it could be different between 32bit or 64bit or so?!

Okay, I wil start to rewrite it with callbacks.

Oh, there was another question: how could I have a function with a kind of "optional" parameter? Like the different possibilities e.g. on:

1
2
3
int QString::compare ( const QString & other, Qt::CaseSensitivity cs ) const
int QString::compare ( const QStringRef & ref, Qt::CaseSensitivity cs = Qt::CaseSensitive ) const
int QString::compare ( const QString & s1, const QStringRef & s2, Qt::CaseSensitivity cs = Qt::CaseSensitive ) [static]


I think it is always the same function "compare" but in the last example there is one more parameter. MAybe if this is possible, I could pass the callback function in the library as optional. So the other calls from the lib itself where not getting confused.
bobc wrote:
Ah, okay. I guess it could be a problem of maybe (long-)int oder float as it could be different between 32bit or 64bit or so?!
That's less common, but yes. Another example is compiling one in debug and the other in release; the debug version will have a different memory lay out for debug variables and such, and when code from debug access release data or release code access debug data, they're interpret it the wrong way (imagine putting a square peg into a round hole, and it works because the round hole is imaginary)

bobc wrote:
I think it is always the same function "compare" but in the last example there is one more parameter. MAybe if this is possible, I could pass the callback function in the library as optional. So the other calls from the lib itself where not getting confused.
In high-level languages, this is called function overloading. Some languages, like C++, also allow you to specify a default value for a parameter to make it optional, rather than defining the function twice.

In C, though, there is no function overloading or default parameters - usually in C you would see this:
1
2
3
4
5
MyFuncEx(int a, int b, int optional);
MyFunc(int a, int b)
{
    MyFuncEx(a, b, 0); //pass default value
}
generally the "Ex" function takes more parameters and does the actual work, and the other one takes the normal parameters and just calls the Ex with default values.
Nice!

Thanks LB for wasting your time on me! It is always very nice to see, that somebody takes care of noobs like me, even if you have to write the same again and again and again and not only refer to "RTFM!"

I will try to adapt my project with your suggestions.
Topic archived. No new replies allowed.