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;
}
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;
}