Passing Stream object by reference

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ian Robertson

    Passing Stream object by reference

    I am trying to write a function that takes a reference to an object as its
    arguement. The object is created in another function and I am trying to pass
    the object to another function from within the function that created the
    object. I have cut out some code as I dont think showing a for loop is
    helpful.

    void TMP3_Main_Form: :LoadMP3()
    {
    TMemoryStream *MP3Stream = new TMemoryStream() ;
    MP3Stream->LoadFromFile(F ileListBox1->Items->Strings[i].c_str());
    GetMP3Data(&MP3 Stream);
    ....
    ....
    ....
    }

    the object is created within this function. I load a file into the stream. I
    then want to pass that stream to another function to perform other tasks on
    the stream.

    My GetMP3Data function accepts a pointer to a stream as its arguement.


    void TMP3_Main_Form: :GetMP3Data(TMe moryStream *MP3)
    {
    char DATA[3]={0,0,0};
    MP3.Position = MP3.Seek(-128,soFromEnd);
    MP3.Read(DATA,3 );

    /* Have tried
    MP3->Position = MP3->Seek(-128,soFromEnd);
    MP3->Read(DATA,3) ;
    also but this didnt seem to work either
    */
    ....
    ....
    ....
    }

    I am having trouble with the * and & operators. I can use and process
    MP3Stream within the LoadTag() function but not with the GetMP3Data
    function. I am trying to avoid having to reload the file from disk from
    scratch in the GetMP3Data function to get the data into the function.
    Ideally I want to be able to load my file once into a stream in memory, do
    my processing with a couple of different functions on the same stream, and
    then rewrite the file back to disk from my updated stream. At the moment I
    have to keep reloading the file from disk as I cant pass by reference
    properly.

    Can anyone help?

    Thanks in advance


  • Rolf Magnus

    #2
    Re: Passing Stream object by reference

    Ian Robertson wrote:
    [color=blue]
    > I am trying to write a function that takes a reference to an object as
    > its arguement. The object is created in another function and I am
    > trying to pass the object to another function from within the function
    > that created the object. I have cut out some code as I dont think
    > showing a for loop is helpful.
    >
    > void TMP3_Main_Form: :LoadMP3()
    > {
    > TMemoryStream *MP3Stream = new TMemoryStream() ;
    > MP3Stream->LoadFromFile(F ileListBox1->Items->Strings[i].c_str());
    > GetMP3Data(&MP3 Stream);
    > ...
    > ...
    > ...
    > }
    >
    > the object is created within this function. I load a file into the
    > stream. I then want to pass that stream to another function to perform
    > other tasks on the stream.
    >
    > My GetMP3Data function accepts a pointer to a stream as its arguement.[/color]

    But above, a pointer to a pointer to a TMemoryStream is passed to
    GetMP3Data. MP3Stream is a pointer to TMemoryStream, and &MP3Stream is
    the address of that pointer. You want to pass the pointer itself, so
    leave out the &.
    [color=blue]
    > void TMP3_Main_Form: :GetMP3Data(TMe moryStream *MP3)
    > {
    > char DATA[3]={0,0,0};
    > MP3.Position = MP3.Seek(-128,soFromEnd);
    > MP3.Read(DATA,3 );
    >
    > /* Have tried
    > MP3->Position = MP3->Seek(-128,soFromEnd);
    > MP3->Read(DATA,3) ;
    > also but this didnt seem to work either
    > */[/color]

    The latter is correct. Are you sure you got the error _within_ that
    function? Unfortunately, you forgot to post the error messages you got.
    [color=blue]
    > ...
    > ...
    > ...
    > }
    >
    > I am having trouble with the * and & operators. I can use and process
    > MP3Stream within the LoadTag() function but not with the GetMP3Data
    > function. I am trying to avoid having to reload the file from disk
    > from scratch in the GetMP3Data function to get the data into the
    > function. Ideally I want to be able to load my file once into a stream
    > in memory, do my processing with a couple of different functions on
    > the same stream, and then rewrite the file back to disk from my
    > updated stream. At the moment I have to keep reloading the file from
    > disk as I cant pass by reference properly.
    >
    > Can anyone help?[/color]

    I wonder where the reference is that you have been talking about at the
    beginning. I only see pointers, no references.

    Comment

    • John Harrison

      #3
      Re: Passing Stream object by reference


      "Rolf Magnus" <ramagnus@t-online.de> wrote in message
      news:c7i5j2$5v0 $00$1@news.t-online.com...[color=blue]
      > Ian Robertson wrote:
      >[color=green]
      > > I am trying to write a function that takes a reference to an object as
      > > its arguement. The object is created in another function and I am
      > > trying to pass the object to another function from within the function
      > > that created the object. I have cut out some code as I dont think
      > > showing a for loop is helpful.
      > >
      > > void TMP3_Main_Form: :LoadMP3()
      > > {
      > > TMemoryStream *MP3Stream = new TMemoryStream() ;
      > > MP3Stream->LoadFromFile(F ileListBox1->Items->Strings[i].c_str());
      > > GetMP3Data(&MP3 Stream);
      > > ...
      > > ...
      > > ...
      > > }
      > >
      > > the object is created within this function. I load a file into the
      > > stream. I then want to pass that stream to another function to perform
      > > other tasks on the stream.
      > >
      > > My GetMP3Data function accepts a pointer to a stream as its arguement.[/color]
      >
      > But above, a pointer to a pointer to a TMemoryStream is passed to
      > GetMP3Data. MP3Stream is a pointer to TMemoryStream, and &MP3Stream is
      > the address of that pointer. You want to pass the pointer itself, so
      > leave out the &.[/color]

      More likely is that the OP should not use new and instead leave in the &,
      like this

      void TMP3_Main_Form: :LoadMP3()
      {
      TMemoryStream MP3Stream;
      MP3Stream->LoadFromFile(F ileListBox1->Items->Strings[i].c_str());
      GetMP3Data(&MP3 Stream);

      Either way, if you use new you already have a pointer and so don't need &,
      if you don't use new then you don't have a pointer and do need &.

      The advantage of not using new is that you don't need to use delete and by
      avoiding heap allocation it is likely to be more efficient.

      john


      Comment

      • John Harrison

        #4
        Re: Passing Stream object by reference

        >[color=blue]
        > void TMP3_Main_Form: :LoadMP3()
        > {
        > TMemoryStream MP3Stream;
        > MP3Stream->LoadFromFile(F ileListBox1->Items->Strings[i].c_str());[/color]

        The above line should also change to

        MP3Stream.LoadF romFile(FileLis tBox1->Items->Strings[i].c_str());
        [color=blue]
        > GetMP3Data(&MP3 Stream);
        >[/color]

        Apologies.

        john


        Comment

        • Rolf Magnus

          #5
          Re: Passing Stream object by reference

          John Harrison wrote:
          [color=blue]
          >
          > "Rolf Magnus" <ramagnus@t-online.de> wrote in message
          > news:c7i5j2$5v0 $00$1@news.t-online.com...[color=green]
          >> Ian Robertson wrote:
          >>[color=darkred]
          >> > I am trying to write a function that takes a reference to an object
          >> > as its arguement. The object is created in another function and I
          >> > am trying to pass the object to another function from within the
          >> > function that created the object. I have cut out some code as I
          >> > dont think showing a for loop is helpful.
          >> >
          >> > void TMP3_Main_Form: :LoadMP3()
          >> > {
          >> > TMemoryStream *MP3Stream = new TMemoryStream() ;
          >> > MP3Stream->LoadFromFile(F ileListBox1->Items->Strings[i].c_str());
          >> > GetMP3Data(&MP3 Stream);
          >> > ...
          >> > ...
          >> > ...
          >> > }
          >> >
          >> > the object is created within this function. I load a file into the
          >> > stream. I then want to pass that stream to another function to
          >> > perform other tasks on the stream.
          >> >
          >> > My GetMP3Data function accepts a pointer to a stream as its
          >> > arguement.[/color]
          >>
          >> But above, a pointer to a pointer to a TMemoryStream is passed to
          >> GetMP3Data. MP3Stream is a pointer to TMemoryStream, and &MP3Stream
          >> is the address of that pointer. You want to pass the pointer itself,
          >> so leave out the &.[/color]
          >
          > More likely is that the OP should not use new and instead leave in the
          > &, like this
          >
          > void TMP3_Main_Form: :LoadMP3()
          > {
          > TMemoryStream MP3Stream;
          > MP3Stream->LoadFromFile(F ileListBox1->Items->Strings[i].c_str());
          > GetMP3Data(&MP3 Stream);[/color]

          I would have suggested that too, but I wasn't sure whether the OP wants
          to use the stream after LoadMP3 (since he said he wanted to write to
          the file later). But I guess you're right. After all, if he wanted to
          use the stream later, it should have been a member variable, or at
          least the function would have to return the pointer.
          [color=blue]
          > Either way, if you use new you already have a pointer and so don't
          > need &, if you don't use new then you don't have a pointer and do need
          > &.[/color]

          Right. However, I'd suggest using a reference instead of a pointer as
          parameter to GetMP3Data. Then, the & is again not needed.
          [color=blue]
          > The advantage of not using new is that you don't need to use delete
          > and by avoiding heap allocation it is likely to be more efficient.[/color]

          Comment

          • Duane Hebert

            #6
            Re: Passing Stream object by reference


            "Rolf Magnus" <ramagnus@t-online.de> wrote in message news:c7i8mk$8p8 $02$1@news.t-online.com...
            [color=blue]
            > I would have suggested that too, but I wasn't sure whether the OP wants
            > to use the stream after LoadMP3 (since he said he wanted to write to
            > the file later). But I guess you're right. After all, if he wanted to
            > use the stream later, it should have been a member variable, or at
            > least the function would have to return the pointer.
            >[color=green]
            > > Either way, if you use new you already have a pointer and so don't
            > > need &, if you don't use new then you don't have a pointer and do need
            > > &.[/color][/color]

            TMemoryStream and TMemoryStream:: LoadFromFile() look like
            Borland VCL classes and functions. If so, the need to be created
            on the heap and can't be instantiated without new. TMemoryStream
            will fit nicely into an auto_ptr though.


            Comment

            • Ian Robertson

              #7
              Re: Passing Stream object by reference

              Many thanks to John and Rolf. I am using borland cpp builder - which forces
              the use of new with TMemoryStreams, and other VCL classes.
              I have used your help to overcome my problem, and the performance gain over
              having to reload the file from disk more than once is very noticable, since
              my program goes through a batch of files at a time, only having to load a
              file once makes a big difference when there are 30-100 files to process.


              "Rolf Magnus" <ramagnus@t-online.de> wrote in message
              news:c7i8mk$8p8 $02$1@news.t-online.com...[color=blue]
              > John Harrison wrote:
              >[color=green]
              > >
              > > "Rolf Magnus" <ramagnus@t-online.de> wrote in message
              > > news:c7i5j2$5v0 $00$1@news.t-online.com...[color=darkred]
              > >> Ian Robertson wrote:
              > >>
              > >> > I am trying to write a function that takes a reference to an object
              > >> > as its arguement. The object is created in another function and I
              > >> > am trying to pass the object to another function from within the
              > >> > function that created the object. I have cut out some code as I
              > >> > dont think showing a for loop is helpful.
              > >> >
              > >> > void TMP3_Main_Form: :LoadMP3()
              > >> > {
              > >> > TMemoryStream *MP3Stream = new TMemoryStream() ;
              > >> > MP3Stream->LoadFromFile(F ileListBox1->Items->Strings[i].c_str());
              > >> > GetMP3Data(&MP3 Stream);
              > >> > ...
              > >> > ...
              > >> > ...
              > >> > }
              > >> >
              > >> > the object is created within this function. I load a file into the
              > >> > stream. I then want to pass that stream to another function to
              > >> > perform other tasks on the stream.
              > >> >
              > >> > My GetMP3Data function accepts a pointer to a stream as its
              > >> > arguement.
              > >>
              > >> But above, a pointer to a pointer to a TMemoryStream is passed to
              > >> GetMP3Data. MP3Stream is a pointer to TMemoryStream, and &MP3Stream
              > >> is the address of that pointer. You want to pass the pointer itself,
              > >> so leave out the &.[/color]
              > >
              > > More likely is that the OP should not use new and instead leave in the
              > > &, like this
              > >
              > > void TMP3_Main_Form: :LoadMP3()
              > > {
              > > TMemoryStream MP3Stream;
              > > MP3Stream->LoadFromFile(F ileListBox1->Items->Strings[i].c_str());
              > > GetMP3Data(&MP3 Stream);[/color]
              >
              > I would have suggested that too, but I wasn't sure whether the OP wants
              > to use the stream after LoadMP3 (since he said he wanted to write to
              > the file later). But I guess you're right. After all, if he wanted to
              > use the stream later, it should have been a member variable, or at
              > least the function would have to return the pointer.
              >[color=green]
              > > Either way, if you use new you already have a pointer and so don't
              > > need &, if you don't use new then you don't have a pointer and do need
              > > &.[/color]
              >
              > Right. However, I'd suggest using a reference instead of a pointer as
              > parameter to GetMP3Data. Then, the & is again not needed.
              >[color=green]
              > > The advantage of not using new is that you don't need to use delete
              > > and by avoiding heap allocation it is likely to be more efficient.[/color]
              >[/color]


              Comment

              Working...