473,395 Members | 1,656 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

passing an array of LPSTR to C++ by reference

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;

}
Jul 22 '05 #1
4 4862
Gent wrote:
[...]
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
Jul 22 '05 #2

"Gent" <ge***********@trustasc.com> wrote in message
news:1b**************************@posting.google.c om...
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
Jul 22 '05 #3
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" <jo*************@hotmail.com> wrote in message news:<2u*************@uni-berlin.de>...
"Gent" <ge***********@trustasc.com> wrote in message
news:1b**************************@posting.google.c om...
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

Jul 22 '05 #4

"Gent" <ge***********@trustasc.com> wrote in message
news:1b*************************@posting.google.co m...
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
Jul 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: domeceo | last post by:
can anyone tell me why I cannot pass values in a setTimeout function whenever I use this function it says "menu is undefined" after th alert. function imgOff(menu, num) { if (document.images) {...
7
by: Mick | last post by:
Does anyone know how to pass an array of structures to a DLL? Here's what I'm doing... the VB.Net error is at the end. *** C++ Structure Declaration: typedef struct _SOME_STRUCT { char...
58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
5
by: Mircea Dragan | last post by:
Hi, I have a problem. Here is the description: I have a dll which I call from a C# program. The C# program passes an array of doubles to the dll function. Everything works fine as long as I...
3
by: dbru | last post by:
I need to pass an address of a Managed float array to a DLL. The following doesn't seem to work extern static float GetXXX( StringBuilder HWND, long nWhat, ref float lparam );
11
by: John Pass | last post by:
Hi, In the attached example, I do understand that the references are not changed if an array is passed by Val. What I do not understand is the result of line 99 (If one can find this by line...
1
by: jg | last post by:
I have searched marshaling articles from MSDN and Google but I am stuck with solving my problem to marshal arrays to COM caller from my managed COM class I built a .net COM class in VB and...
3
by: DaTurk | last post by:
If I call this method, and pass it a byte by ref, and initialize another byte array, set the original equal to it, and then null the reference, why is the original byte array not null as well? I...
4
by: robert.waters | last post by:
I have to parse a binary file having a number of fixed records, each record containing datas in fixed positions. I would like to parse this binary file into an array of structures having members...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.