Returning arrays and Objects in C++

G

Gent

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;

}
 
V

Victor Bazarov

Gent said:
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

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
 
J

John Harrison

Gent said:
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
 
J

Jack Klein

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.
 
G

Gent

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 said:
Gent said:
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

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
 
V

Victor Bazarov

Gent said:
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
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top