passing an array of LPSTR to C++ by reference

G

Gent

Below is a straightforward C++ question but i'm giving example code to
demonstrate the issue i'm having. THe issue might seem to be out of
the topic but it's mostly related to C++ and is not necessarily
environment specific.

I have written a VB program that passes an array of strings to a C++
dll. The c++ dll is supposed to fill the array of strings with the
appropriate value. The only way i figured out how to pass was it by
reference. I create the array and populate with blank spaces in VB
then pass it be reference to C++ dll.

In my C++ example the only values we are concerned about are LPSTR &
strReturnedJobId. Now what happens is that the only value i populate
is the first element of the VB array. It would be a lot easier if i
could declare the header on the C++ function as long __stdcall
GetJobIds(LPSTR & strReturnedJobId[NUMBER_OF_ELEMENT], int
numberOfJobs, int UserSelection)
but apparently you cannot put a & in front of an array declaration.

My question is how do i pass an array of strings by value (from VB) to
a C++ (well this has to be by reference so C++ can fill up the array)
dll. I have no problem solving that if i change the data type from
string to int or so. but as strings do not exist in C++ then i'm
stuck.

Thank you for your help!

Gent




vb 6 code:
my call fails:

Public Declare Function GetJobIds Lib "AdminBits.dll" _
(ByRef strReturnedJobId As String, ByVal intNumberOfJobs As
Integer, ByVal intUserSelection As Integer) As Integer

Private Sub GetBITSJobsGUIDs(ByVal UserSelection As Integer)
Dim numberOfJobs As Integer
numberOfJobs = CountJobs(UserSelection)

Dim LoopArr As Long
Dim arrayOfGUIDs() As String

ReDim arrayOfGUIDs(numberOfJobs - 1) As String

For LoopArr = 0 To numberOfJobs - 1
arrayOfGUIDs(LoopArr) = Space(100)

Next LoopArr
Dim intflag As Integer
'''Attention
intflag = GetJobIds(arrayOfGUIDs(0), numberOfJobs,
UserSelection)


End Sub
c++ code:

long __stdcall GetJobIds(LPSTR & strReturnedJobId, int numberOfJobs,
int UserSelection)
{


USES_CONVERSION; //Use Atlconv.h macros
wchar_t sbuff[100];
LPOLESTR tempstrReturnedJobId = sbuff;
GUID* ReturnedJobId = NULL;

int retvalue = -1;


// If passed in 1 than enumerates jobs for all users
// If passed in 0 than it enumerates job for current user logged on.
// Function returns the number of JOBS or returns -1 if it failed to
count the jobs


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

IBackgroundCopyManager* g_XferManager = NULL;
HRESULT hr;

//Specify the appropriate COM threading model for your application.
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
retvalue = -2;

hr = CoCreateInstance(__uuidof(BackgroundCopyManager), NULL,
CLSCTX_LOCAL_SERVER,
__uuidof(IBackgroundCopyManager),
(void**) &g_XferManager);
if (SUCCEEDED(hr))
{
//failed to enumerate the jobs in the queue.

retvalue = -3;


//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))
{
retvalue = -4; // Could not get the job count

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

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

//Enumerate the jobs in the queue.
for (idx=0; idx<cJobCount; idx++)
{
hr = pJobs->Next(1, &pJob, NULL);
if (S_OK == hr)
{
retvalue = 5; //could not retrieve the job properties such as
ID
//Retrieve or set job properties.


GUID JobId;

pJob->GetId(&JobId);

int abc = StringFromGUID2(JobId, tempstrReturnedJobId, 100);
char *buffer = W2A(tempstrReturnedJobId);

if (40 > strlen(buffer) )
{
//***********ATTENTION HERE ********************
strcpy(&strReturnedJobId[idx], buffer);
//*************end attention *********
retvalue = 1; //successfully got the job IDs
}

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

pJobs->Release();
pJobs = NULL;


}
}
}

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

CoUninitialize();


return retvalue;

}
 
V

Victor Bazarov

Gent said:
[...]
My question is how do i pass an array of strings by value (from VB) to
a C++ (well this has to be by reference so C++ can fill up the array)
dll. I have no problem solving that if i change the data type from
string to int or so. but as strings do not exist in C++ then i'm
stuck. [...]

Please ask in a VB newsgroup or in a Microsoft C++ newsgroup. Here it
is OT because standard C++ has no definition of "passing from VB".

V
 
J

John Harrison

Gent said:
Below is a straightforward C++ question but i'm giving example code to
demonstrate the issue i'm having. THe issue might seem to be out of
the topic but it's mostly related to C++ and is not necessarily
environment specific.

I have written a VB program that passes an array of strings to a C++
dll. The c++ dll is supposed to fill the array of strings with the
appropriate value. The only way i figured out how to pass was it by
reference. I create the array and populate with blank spaces in VB
then pass it be reference to C++ dll.

In my C++ example the only values we are concerned about are LPSTR &
strReturnedJobId. Now what happens is that the only value i populate
is the first element of the VB array. It would be a lot easier if i
could declare the header on the C++ function as long __stdcall
GetJobIds(LPSTR & strReturnedJobId[NUMBER_OF_ELEMENT], int
numberOfJobs, int UserSelection)
but apparently you cannot put a & in front of an array declaration.

Says who?

long GetJobIds(LPSTR (& strReturnedJobId)[NUMBER_OF_ELEMENT], int
numberOfJobs, int UserSelection)

is a prefectly valid declaration. strReturnedJobId is a reference to an
array of size NUMBER_OF_ELEMENT. Whether this is what you need I have no
idea.

john
 
G

Gent

I changed declaration to long __stdcall GetJobIds(LPSTR
(&strReturnedJobId)[100], int numberOfJobs, int UserSelection). It
compiles fine however when i call it from VB the same way as previous
post but i get the error message below:

The instruction at "0x0f473c1" referenced memory at "0x202020020". The
memory could not be written
The instruction at "0x6a9ecd39" referenced memory at "0x0000002c". The
memory could not be read. It bombs at the line where it's trying to do
strcpy(strReturnedJobId[idx], buffer);

I am not sure why I would get that error. Can anyone please tell me
what i'm doing wrong.

Full code is below.

Thanks

Gent Metaj





long __stdcall GetJobIds(LPSTR (&strReturnedJobId)[100], int
numberOfJobs, int UserSelection)
{


USES_CONVERSION; //Use Atlconv.h macros
wchar_t sbuff[100];
LPOLESTR tempstrReturnedJobId = sbuff;
GUID* ReturnedJobId = NULL;

int retvalue = -1;


// If passed in 1 than enumerates jobs for all users
// If passed in 0 than it enumerates job for current user logged on.
// Function returns the number of JOBS or returns -1 if it failed to
count the jobs


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

IBackgroundCopyManager* g_XferManager = NULL;
HRESULT hr;

//Specify the appropriate COM threading model for your application.
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
retvalue = -2;

hr = CoCreateInstance(__uuidof(BackgroundCopyManager), NULL,
CLSCTX_LOCAL_SERVER,
__uuidof(IBackgroundCopyManager),
(void**) &g_XferManager);
if (SUCCEEDED(hr))
{
//failed to enumerate the jobs in the queue.

retvalue = -3;


//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))
{
retvalue = -4; // Could not get the job count

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

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

//Enumerate the jobs in the queue.
for (idx=0; idx<cJobCount; idx++)
{
hr = pJobs->Next(1, &pJob, NULL);
if (S_OK == hr)
{
retvalue = 5; //could not retrieve the job properties such as
ID
//Retrieve or set job properties.


GUID JobId;

pJob->GetId(&JobId);

int abc = StringFromGUID2(JobId, tempstrReturnedJobId, 100);
char *buffer = W2A(tempstrReturnedJobId);

if (40 > strlen(buffer) )
{

strcpy(strReturnedJobId[idx], buffer);
retvalue = 1; //successfully got the job IDs
}

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

pJobs->Release();
pJobs = NULL;


}
}
}

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

CoUninitialize();


return retvalue;

}


John Harrison said:
Gent said:
Below is a straightforward C++ question but i'm giving example code to
demonstrate the issue i'm having. THe issue might seem to be out of
the topic but it's mostly related to C++ and is not necessarily
environment specific.

I have written a VB program that passes an array of strings to a C++
dll. The c++ dll is supposed to fill the array of strings with the
appropriate value. The only way i figured out how to pass was it by
reference. I create the array and populate with blank spaces in VB
then pass it be reference to C++ dll.

In my C++ example the only values we are concerned about are LPSTR &
strReturnedJobId. Now what happens is that the only value i populate
is the first element of the VB array. It would be a lot easier if i
could declare the header on the C++ function as long __stdcall
GetJobIds(LPSTR & strReturnedJobId[NUMBER_OF_ELEMENT], int
numberOfJobs, int UserSelection)
but apparently you cannot put a & in front of an array declaration.

Says who?

long GetJobIds(LPSTR (& strReturnedJobId)[NUMBER_OF_ELEMENT], int
numberOfJobs, int UserSelection)

is a prefectly valid declaration. strReturnedJobId is a reference to an
array of size NUMBER_OF_ELEMENT. Whether this is what you need I have no
idea.

john
 
J

John Harrison

Gent said:
I changed declaration to long __stdcall GetJobIds(LPSTR
(&strReturnedJobId)[100], int numberOfJobs, int UserSelection). It
compiles fine however when i call it from VB the same way as previous
post but i get the error message below:

The instruction at "0x0f473c1" referenced memory at "0x202020020". The
memory could not be written
The instruction at "0x6a9ecd39" referenced memory at "0x0000002c". The
memory could not be read. It bombs at the line where it's trying to do
strcpy(strReturnedJobId[idx], buffer);

I am not sure why I would get that error. Can anyone please tell me
what i'm doing wrong.

The interaction of VB with C++ is not something I know anything about,
neither is it on topic in this group. I just corrected a misconception you
had about C++. You might have better luck in a VB group.

John
 

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,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top