passing array of floats (or vectors) into another function - datascope - hmmm. Very ugly...

S

someone

Hi all,

I got fantastic help in the recent thread about "reading binary file
into memory" and converting from char* etc... I however have a slight
problem, consider this (pseudo)-code:

//--------------------------------------------------------------------
int main(int argc,char **argv)
{
xresReader myBinReader; // my "reader-class" (actually a struct)
myBinReader.readNow(); // read from binary file, put data in memory

unsigned long long N = myBinReader.timesteps_loaded;
cout << "timesteps_loaded = " << N << endl;
cout << "Last time-step found at t= " << myBinReader.RTtime[N-1] <<
" seconds." << endl;

length?? = N; // I need to pass N or length?? to mysample( )
below...

for(int i=1;i<length??;i++)
{
HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;
}

// need to pass these 3 variables to mysample( .. )
// 1) length??
// 2) HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
// 3) HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;



//====================== PLOT ======================
mglGraphFLTK gr;
gr.Window(argc,argv,mysample,"MathGL examples");

return mglFlRun();
}


int mysample(mglGraph *gr, void *) // pseudo-code
{
mglData xvals, yvals;
xvals.Set(HOWTOGETTHISFLOATARRAY_X???, length??);
yvals.Set(HOWTOGETTHISFLOATARRAY_Y???, length??);
gr->Plot(xvals,yvals);
return 0;
}
//--------------------------------------------------------------------


This is getting very ugly... I know this forum is only meant for
discussing standard C++ but I also think this question is a general C+
+ standard question about scoping and passing data arrays around... I
think that for plotting my data, I need this function to take 2 input
arguments: int mysample(mglGraph *gr, void *) so I need to figure out
another way of passing these 3 values (pseudo-variables):

1) length??
2) HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
3) HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;

I can only think of copying my data into a global length-variable and
then from the beginning (not even at run time) allocate two huge
HOWTOGETTHISFLOATARRAY (x+y-coordinates). Then I was thinking about
copying everything into these global arrays... But ugh...

This is really really ugly and therefore I have to ask if there isn't
any better and more nice/clean way of passing my 3 variables to the
plot-function? I think the plotfunction can only have 2 input
arguments, due to the line from which it is called:
gr.Window(argc,argv,mysample,"MathGL examples");

Thanks a lot for any hints / suggestions!
 
V

Victor Bazarov

I got fantastic help in the recent thread about "reading binary file
into memory" and converting from char* etc... I however have a slight
problem, consider this (pseudo)-code:

//--------------------------------------------------------------------
int main(int argc,char **argv)
{
xresReader myBinReader; // my "reader-class" (actually a struct)
myBinReader.readNow(); // read from binary file, put data in memory

unsigned long long N = myBinReader.timesteps_loaded;
cout<< "timesteps_loaded = "<< N<< endl;
cout<< "Last time-step found at t= "<< myBinReader.RTtime[N-1]<<
" seconds."<< endl;

length?? = N; // I need to pass N or length?? to mysample( )
below...

If you create a vector of floats, then there is no need to pass the
length, the vector can always be asked for its size.
for(int i=1;i<length??;i++)

Why from 1?
{
HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;
}

// need to pass these 3 variables to mysample( .. )
// 1) length??
// 2) HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
// 3) HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;


You could try

std::vector<std::pair<double,double> > thisArray(N)
for (int i = 0; i < N; ++i)
{
thisArray.first = myBinReader.X;
thisArray.second = myBinReader.Y;
}
//====================== PLOT ======================
mglGraphFLTK gr;
gr.Window(argc,argv,mysample,"MathGL examples");

return mglFlRun();
}


int mysample(mglGraph *gr, void *) // pseudo-code
{
mglData xvals, yvals;

What's 'mglGraph'? What's 'mglData'?
xvals.Set(HOWTOGETTHISFLOATARRAY_X???, length??);
yvals.Set(HOWTOGETTHISFLOATARRAY_Y???, length??);
gr->Plot(xvals,yvals);
return 0;
}
//--------------------------------------------------------------------


This is getting very ugly... I know this forum is only meant for
discussing standard C++ but I also think this question is a general C+
+ standard question about scoping and passing data arrays around...

What BOOK on C++ are you reading? I am asking because I want to know
what book doesn't explain how to pass local variables to another
function, so that I can recommend others to stay away from such a crappy
book.
I
think that for plotting my data, I need this function to take 2 input
arguments: int mysample(mglGraph *gr, void *) so I need to figure out
another way of passing these 3 values (pseudo-variables):

1) length??

What type is is? Can you declare an argument named "length" and of that
type?
2) HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
3) HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;

I can only think of copying my data into a global length-variable and
then from the beginning (not even at run time) allocate two huge
HOWTOGETTHISFLOATARRAY (x+y-coordinates). Then I was thinking about
copying everything into these global arrays... But ugh...


Pass them by the pointer to the first element. Or create a vector and
pass that vector by a const ref.
This is really really ugly and therefore I have to ask if there isn't
any better and more nice/clean way of passing my 3 variables to the
plot-function?

Is using 'std::vector' or 'std::deque' out of the question for you? If
not, find a book that explains standard *containers* and FCOL learn to
use them. This is such a basic matter that I am cringing at having to
write this...
I think the plotfunction can only have 2 input
arguments, due to the line from which it is called:
gr.Window(argc,argv,mysample,"MathGL examples");

Why do you think the 'plotfunction' has to be limited to those 2 arguments?
Thanks a lot for any hints / suggestions!

Don't mention it.

V
 
S

someone

On 10/17/2011 1:14 PM, someone wrote: ....
If you create a vector of floats, then there is no need to pass the
length, the vector can always be asked for its size.

Actually I already have that. The important thing is to pass the data
into a function without using the arguments. I think I need global
variables and I think I cannot avoid using global variables, because
the function parameters is fixed and the data cannot go in there
because the arguments is used for something else. My idea:

I think I would need 3 global variables:
1) The length (number of elements to read)
2+3) two pointers to a float array of X+Y value pairs to plot.

I can then get the array values by dereferencing, I think... Maybe
that is the best method for me?
Why from 1?

Mistake here, but not in the original code. Because previously I had
something in the subsequent variable, that was as a function of the
previous element number...
   {
     HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
     HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;
   }

   // need to pass these 3 variables to mysample( .. )
   // 1) length??
   // 2) HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
   // 3) HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;


You could try

     std::vector<std::pair<double,double> > thisArray(N)
     for (int i = 0; i < N; ++i)
     {
         thisArray.first = myBinReader.X;
         thisArray.second = myBinReader.Y;
     }


This doesn't solve my data passing problem, you know?

As said, it's the passing of the arrays that is important but not the
data type of the arrays. AFAIR myBinReader.X and myBinReader.Y is
actually already a vector of floats, I just simplified the code I
showed because I didn't want to copy/paste a lot of code pages... And
then also because I'm more familiar with the "C"-type arrays which I
think of as lying out consecutive in memory and I expect that whatever
library I use understands such an array.
What's 'mglGraph'?  What's 'mglData'?

Not sure what mglGraph is. Both are some data types from mathgl
library and it needs the array numbers in mglData before I can plot -
hence, I need to pass x- and y-arrays of numbers to the function
without using the arguments, hence I think I need global variables
(possibly x+y pointers to a float array). Do you agree, that I need
global variables or is there better alternatives which I'm not
familiar/aware of?

-snip-
 > I



What type is is?  Can you declare an argument named "length" and of that
type?

"length??" was pseudocode. Think of it as unsigned long, if you want.
It's not important.
    2) HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
    3) HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;

I can only think of copying my data into a global length-variable and
then from the beginning (not even at run time) allocate two huge
HOWTOGETTHISFLOATARRAY (x+y-coordinates). Then I was thinking about
copying everything into these global arrays... But ugh...

Pass them by the pointer to the first element.  Or create a vector and
pass that vector by a const ref.


What do you mean "pass them by"? How? That is exactly what I ask
about... Maybe I was not clear. I'll just repeat or explain the
problem in another way because I hope to see a few suggestions/
comments from people that knows more than me:

int mysample(mglGraph *gr, void *) // pseudo-code <--- I think that I
cannot change this functions input arguments by adding more (it would
be easy if I could just add more arguments so I can pass the data in
there and avoid the scoping problem by wanting to access data outside
of scope)
{
mglData xvals, yvals; // <--- needs to be filled with my data,
which is outside this scope
....
}
Is using 'std::vector' or 'std::deque' out of the question for you?  If
not, find a book that explains standard *containers* and FCOL learn to
use them.  This is such a basic matter that I am cringing at having to
write this...

But I think you're not understand my problem as I want you to
understand it. Changing the data type or putting it into another
container doesn't help solving the out-of-scope problem I have.
 > I think the plotfunction can only have 2 input


Why do you think the 'plotfunction' has to be limited to those 2 arguments?

Why do you think I can just add more? To answer the question: Because
I don't call it directly. The library calls it, so it expects that the
function has these two arguments. You saw that it's used like this,
right?:

gr.Window(argc,argv,mysample,"MathGL examples");

Meaning that, suppose I *DID* add more input arguments to mysample,
how would you then rewrite the line above and tell the program to pass
your data-array (or container)? You need to pass the arrays and I
haven't seen how you would do that yet.

Thanks. I hope I'm more clear this time and that I can make myself
more "understandable" this time.
 
S

someone

Don't mention it.

Hi,

Ok, now I.... sort of.... solved my problem in a very "C'ish" way.
Maybe there is a better/nicer C++ way?

Let me show what I did to make it work, and maybe it's more clear for
those who care (and if not, I think this solution is acceptable for
me)...


//===============================================
double *xvec; // global
double *yvec; // global
unsigned long long Nlength = 0; // global

int mysample(mglGraph *gr, void *)
{
mglData xvals, yvals;
xvals.Set(xvec,Nlength); // get from global array
yvals.Set(yvec,Nlength); // get from global array
gr->Plot(xvals,yvals); // plot
return 0;
}


int main(int argc,char **argv)
{
xresReader myBinReader; // my "reader-class" (actually a struct)
myBinReader.readNow(); // read from binary file, put data in memory
Nlength = myBinReader.timesteps_loaded;

//====================== PLOT======================
mglGraphFLTK gr;
xvec = new double[Nlength];
yvec = new double[Nlength];
#define sensNum 1
for(unsigned int i=0;i<Nlength;i++)
{
// actually: myBinReader.RTtime is a vector<floats>
xvec = myBinReader.RTtime; // store consecutively
// actually: myBinReader.RTSensor is a vector<
vector<floats> >
yvec = myBinReader.RTSensor[sensNum];
}
gr.Window(argc,argv,mysample,"MathGL examples");
delete[] xvec;
delete[] yvec;

return mglFlRun();
}
//===============================================


Ok, so this is not as stupid as I thought it would be to begin with...
What I do is to allocate memory and have a global pointer that can
then access the allocated array in a function where I (at least) think
that I have no other way of accessing the data (???)...

Maybe it's a simple question for you... When I wrote the first post, I
confused myself a bit. I still think this is not very C++'ish, but
it's the best I can do now, but I would like to learn from someone
here if you have better suggestions :)

Thanks for any comments, if you like... If not, then this is the way
it's gonna be - it works :)
 
V

Victor Bazarov

Actually I already have that. The important thing is to pass the data
into a function without using the arguments.

Why is that "important"?
I think I need global
variables and I think I cannot avoid using global variables, because
the function parameters is fixed and the data cannot go in there
because the arguments is used for something else. My idea:

I think I would need 3 global variables:
1) The length (number of elements to read)
2+3) two pointers to a float array of X+Y value pairs to plot.

I can then get the array values by dereferencing, I think... Maybe
that is the best method for me?

Since I think that the requirement to "pass without passing" is bogus,
everything else is kind of moot. But for the sake of academic
discussion, if you do create global data, why not a simple vector of
pairs, like I showed? You can resize it dynamically when you need to,
and it will destroy itself at the end of the program...
Why from 1?

Mistake here, but not in the original code. Because previously I had
something in the subsequent variable, that was as a function of the
previous element number...
{
HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;
}

// need to pass these 3 variables to mysample( .. )
// 1) length??
// 2) HOWTOGETTHISFLOATARRAY_X??? = myBinReader.X;
// 3) HOWTOGETTHISFLOATARRAY_Y??? = myBinReader.Y;


You could try

std::vector<std::pair<double,double> > thisArray(N)
for (int i = 0; i< N; ++i)
{
thisArray.first = myBinReader.X;
thisArray.second = myBinReader.Y;
}


This doesn't solve my data passing problem, you know?


Well, you can't call it "passing problem" if it's not really a problem
or you're not really passing. Perhaps you could call it the "not
passing problem"... And, again, define that vector outside of any
function and add

thisArray.resize(N);

here instead.
As said, it's the passing of the arrays that is important but not the
data type of the arrays. AFAIR myBinReader.X and myBinReader.Y is
actually already a vector of floats, I just simplified the code I
showed because I didn't want to copy/paste a lot of code pages... And
then also because I'm more familiar with the "C"-type arrays which I
think of as lying out consecutive in memory and I expect that whatever
library I use understands such an array.

Standard vectors actually keep their elements in arrays (contiguous) and
you can pass the address of the first element to any function that needs
an array passed to it.
Not sure what mglGraph is. Both are some data types from mathgl
library and it needs the array numbers in mglData before I can plot -
hence, I need to pass x- and y-arrays of numbers to the function
without using the arguments, hence I think I need global variables
(possibly x+y pointers to a float array). Do you agree, that I need
global variables or is there better alternatives which I'm not
familiar/aware of?

Ah, wait. I think I begin to understand. 'mysample' is a function the
package that plots your graph calls (so called "callback"). In that
case, you can probably supply your own argument (which here will arrive
as the pointer to void) that you need to cast.

Most callbacks provide an alternative way of passing an argument - like
this 'void*' here. When you call their library to initiate the
plotting, you supply the address of some data structure that carries all
the information you need in your callback. The address will be brought
in for the callback to decipher. You static_cast it back from 'void*'
to a pointer to your structure (could be 'std::vector' I was talking
about) and then use the same vector.

V
 
S

someone

......... *cut* .....
Ah, wait.  I think I begin to understand.  'mysample' is a function the
package that plots your graph calls (so called "callback").  In that
case, you can probably supply your own argument (which here will arrive
as the pointer to void) that you need to cast.

Aah, ok... I know "callback"-functions from Matlab GUI-programming.
Makes sense. I didn't know that was the name here. Thanks for learning
me to use a (technically more correct word) term, that I didn't knew
could be used to better describe my problem. Next time I get this
problem, I'll call it a callback-function so it's more clear to other
people :)

I couldn't / don't really understand this pointer to void. Why isn't
there any name for that pointer to void?
Most callbacks provide an alternative way of passing an argument - like
this 'void*' here.  When you call their library to initiate the

So you think I could use this void* here without doing my global
variable stuff? That would be better, IMHO... If it had a name of that
pointer to void, maybe I could create a structure holding all my data
and then cast the pointer to void into that structure type? Does that
make sense and is that how people typically do it?
plotting, you supply the address of some data structure that carries all
the information you need in your callback.  The address will be brought
in for the callback to decipher.  You static_cast it back from 'void*'
to a pointer to your structure (could be 'std::vector' I was talking
about) and then use the same vector.

Ok... I still haven't understood exactly these different types of
casting... So, are you convinced that this pointer to void is for my
own user-supplied input arguments and that the callback doesn't use
this pointer to void for anything?

Maybe I could make a little test and avoid this ugly global mumbo
jumbo-stuff completely, if you're convinced that this is probably the
intended point of having the pointer-to-void input argument...?

Also, if you/somebody has time - disregard my first post(s) and see
the working global code I posted later... I knew (had the feeling),
that I was not doing it right / in the best way...
 
V

Victor Bazarov

Don't mention it.

Hi,

Ok, now I.... sort of.... solved my problem in a very "C'ish" way.
Maybe there is a better/nicer C++ way?

Let me show what I did to make it work, and maybe it's more clear for
those who care (and if not, I think this solution is acceptable for
me)...


//===============================================
double *xvec; // global
double *yvec; // global
unsigned long long Nlength = 0; // global

int mysample(mglGraph *gr, void *)
{
mglData xvals, yvals;
xvals.Set(xvec,Nlength); // get from global array
yvals.Set(yvec,Nlength); // get from global array
gr->Plot(xvals,yvals); // plot
return 0;
}


int main(int argc,char **argv)
{
xresReader myBinReader; // my "reader-class" (actually a struct)
myBinReader.readNow(); // read from binary file, put data in memory
Nlength = myBinReader.timesteps_loaded;

//====================== PLOT ======================
mglGraphFLTK gr;
xvec = new double[Nlength];
yvec = new double[Nlength];
#define sensNum 1
for(unsigned int i=0;i<Nlength;i++)
{
// actually: myBinReader.RTtime is a vector<floats>
xvec = myBinReader.RTtime; // store consecutively
// actually: myBinReader.RTSensor is a vector<
vector<floats> >
yvec = myBinReader.RTSensor[sensNum];
}
gr.Window(argc,argv,mysample,"MathGL examples");


Apparently you're supplying the name (and behind that name there is a
pointer) to your function-callback. For whatever reason the 'Window'
needs 'argc', 'argv' (probalby so that you can give command-line
arguments to your executable and they get transmitted over to the
'mglGraphFLTK' toolkit). Do you see "MathGL examples" written anywhere
when your window ('gr') is shown? If so, the fourth argument to the
'Window' member function of the toolkit object is the title (probably).
Where would you pass your argument? You need to read about the
callback function. It should explain the role of the second argument,
where it comes from and how to set it in your program.

You can give it a name in your 'mysample' implementation:

int mysample(mglGraph* gr, void* some_data)

but the documentation should explain what to do with it.
delete[] xvec;
delete[] yvec;

return mglFlRun();
}
//===============================================


Ok, so this is not as stupid as I thought it would be to begin with...
What I do is to allocate memory and have a global pointer that can
then access the allocated array in a function where I (at least) think
that I have no other way of accessing the data (???)...

Maybe it's a simple question for you... When I wrote the first post, I
confused myself a bit. I still think this is not very C++'ish, but
it's the best I can do now, but I would like to learn from someone
here if you have better suggestions :)

Thanks for any comments, if you like... If not, then this is the way
it's gonna be - it works :)

Global data have bad rap - they aren't very nice, not thread-safe, etc.
They can change when you're working with them, no good scope or
lifetime control, and that's why [justifiedly] many don't like global
data. It's much better to pass parameters. Prefer parameter passing
over global data any day of the week.

V
 
W

Werner

[snip]
Maybe it's a simple question for you... When I wrote the first post, I
confused myself a bit. I still think this is not very C++'ish, but
it's the best I can do now, but I would like to learn from someone
here if you have better suggestions :)

Thanks for any comments, if you like... If not, then this is the way
it's gonna be - it works :)

Adding to what Victor said, I've looked at the interface, and I think
this is a better example of what you should do. I've replaced the
library classes with my own placeholders. Note that no private
data exists. This compiles and runs fine courtesy of ideone.

#include <vector>

struct mglGraph
{
};

struct xresReader
{
std::vector<float> RTTime;
std::vector<std::vector<float> > RTSensor;
};

class mglGraphAB
{
public:
void Window(
int argc, char **argv, int (*draw)(mglGraph *gr, void *p),
const char *title, void *par=NULL, void (*reload)(int
next)=NULL )
{
//For example, what library code might look like...
mglGraph gr;
draw( &gr, par );
}
};

int mysample_impl( mglGraph*, xresReader* )
{
//Do work here!!! All xresReader data available...
return 0;
}

int mysample( mglGraph *gr, void* param )
{
//Delegate work to ...impl.
return mysample_impl( gr, static_cast<xresReader*>( param ) );
}

int main( int argc, char **argv )
{
//[snip]

//Ensure scope of xresReader exceeds that of mglGraphAB.
//They might be encapsulated in a class as members...

xresReader myBinReader;
mglGraphAB gr;
gr.Window( argc, argv, mysample, "My Window", &myBinReader );
return 0;
}
 
S

someone

On 10/17/2011 3:20 PM, someone wrote: .....
   #define sensNum 1
   for(unsigned int i=0;i<Nlength;i++)
           {
           // actually: myBinReader.RTtime is a vector<floats>
   xvec = myBinReader.RTtime; // store consecutively
           // actually: myBinReader.RTSensor is a vector<
vector<floats>  >
   yvec = myBinReader.RTSensor[sensNum];
           }
   gr.Window(argc,argv,mysample,"MathGL examples");


Apparently you're supplying the name (and behind that name there is a
pointer) to your function-callback.  For whatever reason the 'Window'
needs 'argc', 'argv' (probalby so that you can give command-line
arguments to your executable and they get transmitted over to the
'mglGraphFLTK' toolkit).  Do you see "MathGL examples" written anywhere


Ah, sounds reasonable. Yes, "MathGL examples" is the title of the
window, shown next to the minimize/maximize buttons.
when your window ('gr') is shown?  If so, the fourth argument to the
'Window' member function of the toolkit object is the title (probably).

I found out that when I type some invalid, I get this command line
argument help:

options are:
-bg2 color
-bg color
-di[splay] host:n.n
-dn[d]
-fg color
-g[eometry] WxH+X+Y
-i[conic]
-k[bd]
-na[me] classname
-nod[nd]
-nok[bd]
-not[ooltips]
-s[cheme] scheme
-ti[tle] windowtitle
-to[oltips]

So, e.g. I can run the program as: "./a.out ti THIS IS A NEW TITLE"
and then that title replaces the "MathGL examples" title...
  Where would you pass your argument?  You need to read about the
callback function.  It should explain the role of the second argument,
where it comes from and how to set it in your program.

Ok, got it.
You can give it a name in your 'mysample' implementation:

     int mysample(mglGraph* gr, void* some_data)

but the documentation should explain what to do with it.

Thanks - I look at it a bit later, I had a long day doing a few other
things!
   delete[] xvec;
   delete[] yvec;
   return mglFlRun();
}
//===============================================
Ok, so this is not as stupid as I thought it would be to begin with...
What I do is to allocate memory and have a global pointer that can
then access the allocated array in a function where I (at least) think
that I have no other way of accessing the data (???)...
Maybe it's a simple question for you... When I wrote the first post, I
confused myself a bit. I still think this is not very C++'ish, but
it's the best I can do now, but I would like to learn from someone
here if you have better suggestions :)
Thanks for any comments, if you like... If not, then this is the way
it's gonna be - it works :)

Global data have bad rap - they aren't very nice, not thread-safe, etc.
  They can change when you're working with them, no good scope or
lifetime control, and that's why [justifiedly] many don't like global
data.  It's much better to pass parameters.  Prefer parameter passing
over global data any day of the week.

Yes, I understand that... I feel the same about global data - I try to
avoid using them... Glad to hear your comments. Thanks for that.
 
S

someone

[snip]
Maybe it's a simple question for you... When I wrote the first post, I
confused myself a bit. I still think this is not very C++'ish, but
it's the best I can do now, but I would like to learn from someone
here if you have better suggestions :)
Thanks for any comments, if you like... If not, then this is the way
it's gonna be - it works :)

Adding to what Victor said, I've looked at the interface, and I think
this is a better example of what you should do. I've replaced the
library classes with my own placeholders. Note that no private
data exists. This compiles and runs fine courtesy of ideone.

Thanks a lot for doing that! Fantastic work - I must say that I had to
add "include<stdlib.h>" for it to compile, but it looks really good
and definately, there's something I can learn from...

I tried to modify your code and use it on my own - however I get a
"segmentation fault" - not sure why... I'll have to look into it and
prepare/post a better reply tomorrow... It's really a great help, that
you made this. Thanks - I'll be back, after I've slept (am too tired
now)...
 
W

Werner

Thanks a lot for doing that! Fantastic work - I must say that I had to
add "include<stdlib.h>" for it to compile, but it looks really good
and definately, there's something I can learn from...

Rather use <cstdlib>. It caters for c++ better (as opposed to c).
Yes, the compiler I used did not require additional includes
for NULL. I cut and paste the definition from the graph
API without looking.
I tried to modify your code and use it on my own - however I get a
"segmentation fault" - not sure why...

The code I gave you runs as is. You can view the output
of this:

http://ideone.com/JIlfF

I've modified mysample_impl to access the reader as proof of
concept. This would mean you have some problem in your code.

In:

gr.Window( argc, argv, mysample, "My Window", &myBinReader );

I would make sure that myBinReader starts out simply. You can
even make it an integer or a vector of ints to test the
concept. Remember to replace the placeholders with the
actual graph API...

Regards,

Werner
 
J

Jorgen Grahn

.
Most callbacks provide an alternative way of passing an argument - like
this 'void*' here.

And those that /don't/ are broken by design. I see them far too often.

/Jorgen
 
S

someone

On Mon, 2011-10-17, Victor Bazarov wrote:

...


And those that /don't/ are broken by design. I see them far too often.

I think we all more or less agree now...

When you see these broken designs (where it's not possible to pass
additional user-defined arguments), then you'll have to go for a
solution with global variables, right? I mean, something similar to
what I came up with after about 3 posts?

There is no alternative to using global vars in that case, at least
not AFAIK - is this right or not?
 
S

someone

Rather use <cstdlib>. It caters for c++ better (as opposed to c).
Yes, the compiler I used did not require additional includes
for NULL. I cut and paste the definition from the graph
API without looking.

Ok. It's really great. I appreciate it a lot - extremely helpful for
me...
The code I gave you runs as is. You can view the output
of this:

http://ideone.com/JIlfF

I've modified mysample_impl to access the reader as proof of
concept. This would mean you have some problem in your code.

Yep - it's a really great example which I can learn (and have learned)
a lot from.
In:

gr.Window( argc, argv, mysample, "My Window", &myBinReader );

I would make sure that myBinReader starts out simply. You can

Ok, my data passing / argument passing code works now... I just have
another problem, which I think I can solve myself... The plot looks
wrong... I think that the x-axis is wrong even though the text for the
xlabel looks right. I'm actually a bit disappointed about this mathgl-
library... But that is perhaps not something to discuss here...
even make it an integer or a vector of ints to test the
concept. Remember to replace the placeholders with the
actual graph API...

Yep! It works (except that the graph looks wrong, but I think this is
a bug not related to the argument passing).

I spend approx. 5 hours figuring out what was wrong and why I got a
segmentation fault... Turned out that I had to replace this line:

gr.Window(argc,argv,mysample,"My window");

With this line:

gr.Window(argc,argv,mysample,"My window", &myBinReader);

Well... I learned my lesson now and next time, I'll not do so many
mistakes with passing arguments to callback-functions :)

Thanks a lot! The replies I got was a huge (invaluable) help to me and
I would never have sorted this out myself... :)
 
S

someone

"private" should be "global". Sorry!

Code can be viewed here:

http://ideone.com/mrePw

By the way: How come you code on that webpage? Or I assume you made the
program on your own pc and then copy/pasted it?

I'm not familiar with that webpage, but I tried to clone the code and
run it and modified it slightly... I prefer to code on my own pc, rather
than to use a webbased online webcoding solution (or whatever it's
called)...

?

Not that I mind other people using it... Just wondering...
 
S

someone

Global variables break down hard in case of multithreading. In this case
one can use thread-specific storage, the boost::thread library provides
some cross-platform support for it for example. This still has all other
drawbacks of globals.

Ok, so boost:thread has some kind of data type that is only "global" to
a single thread, unlike global to all threads...

Ok, I'll remember that in case I'll ever need it, thanks...
 
J

Jorgen Grahn

I think we all more or less agree now...

When you see these broken designs (where it's not possible to pass
additional user-defined arguments), then you'll have to go for a
solution with global variables, right?

Yes -- or rewrite the callback interface if you can.
There is no alternative to using global vars in that case, at least
not AFAIK - is this right or not?

Perhaps I used the word "global" a bit sloppily; it could e.g. be
something like:

int * get_the_data()
{
static int foo;
return &foo;
}

but that doesn't really help much.

/Jorgen
 
S

someone

Perhaps I used the word "global" a bit sloppily; it could e.g. be
something like:

int * get_the_data()
{
static int foo;
return&foo;
}

but that doesn't really help much.

Because that is not thread-safe ? Not sure I understand why "global" was
used sloppily, neither not sure of the purpose of this get_the_data()
function. Isn't this get_the_data() function a global function, so
instead foo could just as well be a global variable - the result is the
same: Ugly?

Foo is static, so it exists until the program terminates... Static is
not thread-safe, right? I think I can see that this doesn't really help
much, I'm just only 95% sure of the explanation...
 
W

Werner

By the way: How come you code on that webpage? Or I assume you made the
program on your own pc and then copy/pasted it?

perhaps OT... but

- I don't need to create a project everytime.
- I can use the latest compiler...
- It's a nice way of sharing ideas. It's certainly a
better way of looking at the code that using a
newsreader. [You] can compile and run it
immediately
- The only disadvantage I see is that I don't know
how persistent the code is (how long it will remain
there).

Of course when I do work I code on my PC/Notebook etc.

Glad to be of help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,526
Members
44,997
Latest member
mileyka

Latest Threads

Top