Returning arrays and Objects in C++

Discussion in 'C++' started by Gent, Sep 15, 2004.

  1. Gent

    Gent Guest

    I have two questions which are very similar:
    Is it possible to return an object in C++. Below is part of my code
    for reference however I am more concerned about the concept. It seems
    like the function below is returning a pointer to pointers who are
    GUID. I am trying to write a wrapper to use in my VB code and what I
    would prefer to do is be able to return an array of GUID. I remember
    (not sure) that the concept of arrays does not really exist in c++ and
    they are all pointers however, i do not want to pass a pointer to the
    global IdsOfJobs i would like to pass the array itself. So is it
    possible to return an array of objects. I would like to be able to
    change the function definition to

    GUID** AdminBits::GetJobIDs(int UserSelection, int& NumberOfJobs).


    Thank you for your time. Also my second question is in regards to
    creating COM+ components using VC++. Is there any easy to follow
    tutorial? I have my classes written and working as a WIN32 Console
    application. Having difficulties when I try to Create an instance of
    the DLL object from VB.
    Thanks a bunch.

    Gent

    Code below for reference

    -------------------------------------------------
    -------------------------------------------------
    Declared inside the class AdminBits
    Class AdminBits {
    .....
    IBackgroundCopyManager* g_XferManager;
    HRESULT hr;
    GUID** IdsOfJobs;

    .....
    };

    GUID** AdminBits::GetJobIDs(int UserSelection, int& NumberOfJobs)
    {
    // GUID *tempIDs;
    // GUID tempIDs[100];
    GUID temp;
    int i = 0;

    // If passed in 1 than enumerates jobs for all users
    // If passed in 0 than it enumerates job for current user logged on.


    IEnumBackgroundCopyJobs* pJobs = NULL;
    IBackgroundCopyJob* pJob = NULL;
    ULONG cJobCount = 0;
    ULONG idx = 0;

    //Specify the appropriate COM threading model for your application.
    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (SUCCEEDED(hr))
    {
    //The impersonation level must be at least
    RPC_C_IMP_LEVEL_IMPERSONATE.
    hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
    RPC_C_AUTHN_LEVEL_CONNECT,
    RPC_C_IMP_LEVEL_IMPERSONATE,
    NULL, EOAC_NONE, 0);
    if (SUCCEEDED(hr))
    {
    hr = CoCreateInstance(__uuidof(BackgroundCopyManager), NULL,
    CLSCTX_LOCAL_SERVER,
    __uuidof(IBackgroundCopyManager),
    (void**) &g_XferManager);


    //Enumerate jobs in the queue. This example enumerates all jobs in
    the transfer
    //queue. This call fails if the current user does not have
    administrator
    //privileges. To enumerate jobs for only the current user, replace
    //BG_JOB_ENUM_ALL_USERS with 0.

    if(UserSelection == 1)
    {
    hr = g_XferManager->EnumJobs(BG_JOB_ENUM_ALL_USERS, &pJobs);
    }
    else
    {
    hr = g_XferManager->EnumJobs(0, &pJobs);
    }


    if (SUCCEEDED(hr))
    {
    //Get the count of jobs in the queue.
    pJobs->GetCount(&cJobCount);

    // IdsOfJobs= new GUID*[cJobCount+1];

    NumberOfJobs = cJobCount;


    //Enumerate the jobs in the queue.
    for (idx=0; idx<cJobCount; idx++)
    {
    hr = pJobs->Next(1, &pJob, NULL);
    if (S_OK == hr)
    {
    pJob->GetId(&temp);
    IdsOfJobs = &temp;
    // tempIDs = temp;
    i++;
    //Retrieve or set job properties.

    pJob->Release();
    pJob = NULL;
    }
    else
    {
    //Handle error
    break;
    }
    }
    }
    }
    }

    if (g_XferManager)
    {
    g_XferManager->Release();
    g_XferManager = NULL;
    }

    CoUninitialize();


    return IdsOfJobs;

    }
     
    Gent, Sep 15, 2004
    #1
    1. Advertising

  2. Gent wrote:
    > I have two questions which are very similar:
    > Is it possible to return an object in C++.


    Most certainly.

    > Below is part of my code
    > for reference however I am more concerned about the concept. It seems
    > like the function below is returning a pointer to pointers who are
    > GUID.


    That's right.

    > I am trying to write a wrapper to use in my VB code and what I
    > would prefer to do is be able to return an array of GUID.


    It is impossible to return an array from a function.

    > I remember
    > (not sure) that the concept of arrays does not really exist in c++ and
    > they are all pointers however, i do not want to pass a pointer to the
    > global IdsOfJobs i would like to pass the array itself. So is it
    > possible to return an array of objects. I would like to be able to
    > change the function definition to
    >
    > GUID** AdminBits::GetJobIDs(int UserSelection, int& NumberOfJobs).


    But you did, didn't you? And you're still returning a pointer to
    a pointer to GUID, and not an array.

    > Thank you for your time. Also my second question is in regards to
    > creating COM+ components using VC++. Is there any easy to follow
    > tutorial? I have my classes written and working as a WIN32 Console
    > application. Having difficulties when I try to Create an instance of
    > the DLL object from VB.


    That is OT here. Please find a better NG to ask your COM+ question.

    > Code below for reference
    >
    > -------------------------------------------------
    > -------------------------------------------------
    > Declared inside the class AdminBits
    > Class AdminBits {


    I believe you mean

    class AdminBits {

    C++ is case-sensitive, and there is no keyword "Class" in it.

    > .....
    > IBackgroundCopyManager* g_XferManager;
    > HRESULT hr;
    > GUID** IdsOfJobs;


    A data member which is a pointer to a pointer.

    >
    > .....
    > };
    >
    > GUID** AdminBits::GetJobIDs(int UserSelection, int& NumberOfJobs)
    > {
    > GUID temp;


    An automatic object of type GUID. This object will go away

    > [...]
    > //Enumerate the jobs in the queue.
    > for (idx=0; idx<cJobCount; idx++)
    > {
    > [...]
    > IdsOfJobs = &temp;


    You're accessing the i-th element of an [imaginary] array pointed to
    by the 'IdsOfJobs' pointer. Does the array exist? Where is that
    array created? That's unknown and you don't show it in your code.
    Second, no less drastic, error is taking (and storing) an address of
    an automatic object. 'temp' _shall_ be destroyed as soon as this
    member function returns the control to its caller. That means that
    the pointers you stored in that [imaginary] array are not valid any
    longer (besides the fact that they all are the same).

    > [...]
    > }
    > }
    > }
    > }
    > [...]
    > return IdsOfJobs;
    >
    > }


    I don't know how VB deals with connecting to C++ programs (this is
    not the right place to discuss it), but you might be better off just
    passing an empty array of the right size to the function and expect
    the function to fill it.

    Victor
     
    Victor Bazarov, Sep 15, 2004
    #2
    1. Advertising

  3. "Gent" <> wrote in message
    news:...
    >I have two questions which are very similar:
    > Is it possible to return an object in C++.


    Yes.

    > Below is part of my code
    > for reference however I am more concerned about the concept. It seems
    > like the function below is returning a pointer to pointers who are
    > GUID. I am trying to write a wrapper to use in my VB code and what I
    > would prefer to do is be able to return an array of GUID.


    Arrays are not objects, it is not possible to return arrays in C++.

    > I remember
    > (not sure) that the concept of arrays does not really exist in c++ and
    > they are all pointers however,


    That is a badly confused understanding of a tricky concept. Arrays certainly
    exist in C++ but they are somewhat limited and pointers are sometimes used
    to get round some of those limitations. In particular you cannot return an
    array in C++ but you can return a pointer which points to the first element
    of an array.

    > i do not want to pass a pointer to the
    > global IdsOfJobs i would like to pass the array itself.


    You cannot pass arrays either, but you can pass a pointer which points to
    the first element of an array.

    > So is it
    > possible to return an array of objects. I would like to be able to
    > change the function definition to


    It's not possible to return an array in C++.

    >
    > GUID** AdminBits::GetJobIDs(int UserSelection, int& NumberOfJobs).


    That is a function returning a pointer not an array. Its a perfectly legal
    declaration.

    I think you need to revise pointers and arrays and the similarities and
    differences. Any book on C or C++ will cover this. In particular you seem to
    be confusing functions which return a pointer, which happens to point to the
    first element of an array, (legal) with a functions which return an array
    (illegal), they are not the same thing at all.

    >
    > Thank you for your time. Also my second question is in regards to
    > creating COM+ components using VC++. Is there any easy to follow
    > tutorial? I have my classes written and working as a WIN32 Console
    > application. Having difficulties when I try to Create an instance of
    > the DLL object from VB.
    > Thanks a bunch.


    COM+ is not on topic in this group.

    john
     
    John Harrison, Sep 15, 2004
    #3
  4. Gent

    Jack Klein Guest

    On Wed, 15 Sep 2004 22:46:39 +0100, "John Harrison"
    <> wrote in comp.lang.c++:

    >
    > "Gent" <> wrote in message
    > news:...
    > >I have two questions which are very similar:
    > > Is it possible to return an object in C++.

    >
    > Yes.
    >
    > > Below is part of my code
    > > for reference however I am more concerned about the concept. It seems
    > > like the function below is returning a pointer to pointers who are
    > > GUID. I am trying to write a wrapper to use in my VB code and what I
    > > would prefer to do is be able to return an array of GUID.

    >
    > Arrays are not objects, it is not possible to return arrays in C++.


    Arrays are so objects in C++, although it is not possible to return
    bare arrays.

    ========
    [intro.object] 1.8 The C++ object model

    1 The constructs in a C++ program create, destroy, refer to, access,
    and manipulate objects. An object is a region of storage. [Note: A
    function is not an object, regardless of whether or not it occupies
    storage in the way that objects do. ] An object is created by a
    definition (3.1), by a new expression (5.3.4) or by the implementation
    (12.2) when needed. The properties of an object are determined when
    the object is created. An object can have a name (clause 3). An object
    has a storage duration (3.7) which influences its lifetime (3.8). An
    object has a type (3.9). The term object type refers to the type with
    which the object is created.
    ========

    While bare arrays cannot be passed to, or returned from, functions by
    value, encapsulated arrays can.

    struct encapsulated_array
    {
    int array [10];
    };

    encapsulated_array some_func(encapsulated_array);

    Perfectly valid.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Sep 16, 2004
    #4
  5. Gent

    Gent Guest

    Thank you for your reply Victor. I actually like the idea of passing
    an empty array to the function and have the function fill it. I will
    try it today. However I am not sure how to resize an array in C++. I
    might not know the size of the array before I pass it to the function.
    Is it possible to do that? If not I will break down the function in
    two pieces. One the finds out the number of elements (size of array)
    and the other one that gets the info.
    I plan on changing the function declaration to
    bool AdminBits::GetJobIDs(int UserSelection, int& NumberOfJobs, GUID&
    IdSofJobs[])
    {
    // how can i resize the IdSofJobs inside here. I can calculate the
    NumberOfJobs and I wantet that to be of size [NumberOfJobs+1]


    }


    Thanks,

    Gent

    > I don't know how VB deals with connecting to C++ programs (this is
    > not the right place to discuss it), but you might be better off just
    > passing an empty array of the right size to the function and expect
    > the function to fill it.
    >
    > Victor


    Victor Bazarov <> wrote in message news:<fy22d.2075$09.us.to.verio.net>...
    > Gent wrote:
    > > I have two questions which are very similar:
    > > Is it possible to return an object in C++.

    >
    > Most certainly.
    >
    > > Below is part of my code
    > > for reference however I am more concerned about the concept. It seems
    > > like the function below is returning a pointer to pointers who are
    > > GUID.

    >
    > That's right.
    >
    > > I am trying to write a wrapper to use in my VB code and what I
    > > would prefer to do is be able to return an array of GUID.

    >
    > It is impossible to return an array from a function.
    >
    > > I remember
    > > (not sure) that the concept of arrays does not really exist in c++ and
    > > they are all pointers however, i do not want to pass a pointer to the
    > > global IdsOfJobs i would like to pass the array itself. So is it
    > > possible to return an array of objects. I would like to be able to
    > > change the function definition to
    > >
    > > GUID** AdminBits::GetJobIDs(int UserSelection, int& NumberOfJobs).

    >
    > But you did, didn't you? And you're still returning a pointer to
    > a pointer to GUID, and not an array.
    >
    > > Thank you for your time. Also my second question is in regards to
    > > creating COM+ components using VC++. Is there any easy to follow
    > > tutorial? I have my classes written and working as a WIN32 Console
    > > application. Having difficulties when I try to Create an instance of
    > > the DLL object from VB.

    >
    > That is OT here. Please find a better NG to ask your COM+ question.
    >
    > > Code below for reference
    > >
    > > -------------------------------------------------
    > > -------------------------------------------------
    > > Declared inside the class AdminBits
    > > Class AdminBits {

    >
    > I believe you mean
    >
    > class AdminBits {
    >
    > C++ is case-sensitive, and there is no keyword "Class" in it.
    >
    > > .....
    > > IBackgroundCopyManager* g_XferManager;
    > > HRESULT hr;
    > > GUID** IdsOfJobs;

    >
    > A data member which is a pointer to a pointer.
    >
    > >
    > > .....
    > > };
    > >
    > > GUID** AdminBits::GetJobIDs(int UserSelection, int& NumberOfJobs)
    > > {
    > > GUID temp;

    >
    > An automatic object of type GUID. This object will go away
    >
    > > [...]
    > > //Enumerate the jobs in the queue.
    > > for (idx=0; idx<cJobCount; idx++)
    > > {
    > > [...]
    > > IdsOfJobs = &temp;

    >
    > You're accessing the i-th element of an [imaginary] array pointed to
    > by the 'IdsOfJobs' pointer. Does the array exist? Where is that
    > array created? That's unknown and you don't show it in your code.
    > Second, no less drastic, error is taking (and storing) an address of
    > an automatic object. 'temp' _shall_ be destroyed as soon as this
    > member function returns the control to its caller. That means that
    > the pointers you stored in that [imaginary] array are not valid any
    > longer (besides the fact that they all are the same).
    >
    > > [...]
    > > }
    > > }
    > > }
    > > }
    > > [...]
    > > return IdsOfJobs;
    > >
    > > }

    >
    > I don't know how VB deals with connecting to C++ programs (this is
    > not the right place to discuss it), but you might be better off just
    > passing an empty array of the right size to the function and expect
    > the function to fill it.
    >
    > Victor
     
    Gent, Sep 16, 2004
    #5
  6. Gent wrote:
    > Thank you for your reply Victor. I actually like the idea of passing
    > an empty array to the function and have the function fill it. I will
    > try it today. However I am not sure how to resize an array in C++. I
    > might not know the size of the array before I pass it to the function.
    > Is it possible to do that? If not I will break down the function in
    > two pieces. One the finds out the number of elements (size of array)
    > and the other one that gets the info.
    > I plan on changing the function declaration to
    > bool AdminBits::GetJobIDs(int UserSelection, int& NumberOfJobs, GUID&
    > IdSofJobs[])


    No, that's not going to work. There is no array of references. You will
    still need a pointer, but the outside function should pass an array to
    'GetJobIDs':

    bool ... , GUID *IDsOfJobs);
    ....
    GUID IDsOfJobs[100];
    ....
    blah.GetJobIDs(..., IDsOfJobs);

    > {
    > // how can i resize the IdSofJobs inside here. I can calculate the
    > NumberOfJobs and I wantet that to be of size [NumberOfJobs+1]
    >
    >
    > }


    The usual way is to return the necessary number of jobs if the pointer
    passed is NULL (IDsOfJobs == NULL). See DeviceCapabilities Windows SDK
    function as an example: if its fourth argument is NULL, it returns the
    number of bytes required. Yes, it would require two calls, but short of
    allocating memory in the function itself, that's all you can do usually
    to get the array sized properly.

    Another way, of course, is to give it an array sized definitely larger
    than it might ever be necessary. Yet another way is to tell the function
    how big the array is and ask only for as many Job IDs as there are array
    elements. Yet another way is to actually implement a Job ID _enumeration_
    procedure and organize your interaction that way (see EnumDesktopWindows
    function in Windows SDK for an example of using a callback).

    >
    >
    > Thanks,
    >
    > Gent
    >
    > [...]


    V
     
    Victor Bazarov, Sep 16, 2004
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alexandra Stehman
    Replies:
    5
    Views:
    30,664
    Chris Smith
    Jun 17, 2004
  2. Pete
    Replies:
    10
    Views:
    560
    John F. Bode
    Sep 22, 2004
  3. 7stud
    Replies:
    11
    Views:
    700
    Dennis Lee Bieber
    Mar 20, 2007
  4. Philipp
    Replies:
    21
    Views:
    1,135
    Philipp
    Jan 20, 2009
  5. ThomasW
    Replies:
    11
    Views:
    287
    ThomasW
    Sep 28, 2009
Loading...

Share This Page