Hi,

I need to call a function, like dummy_fun( LPCTSTR * ppStr ), the ppStr
parameter's data is stored in a database, so this parameter cannot be
initialized using syntax like LPCTSTR ppStr[] = {_T("AAA"), ..., NULL }.

Following code is used to retrieve data from database and stored them to a
vector and construct the ppStr parameter.

//...
std::vector<CString> vs;
while ( SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET) {
DBSTATUS dt;
rs.GetStatus(_T("ItemText"), &dt);
if (dt == DBSTATUS_S_OK) {
CString str((LPCTSTR)rs.GetValue(_T("ItemText")));
if (!str.IsEmpty()) {
vs.push_back(str);
}
}
hr = rs.MoveNext();
}

LPCTSTR *ppStr = new LPCTSTR[vs.size() + 1];

size_t i = 0, vsMax = vs.size();
while ( i < vsMax) { ppStr[i] = vs[i]; ++i;}
ppStr[vsMax] = NULL; // terminating NULL
dummy_function( ppStr ); // This function has a LPCTSTR * parameter
delete[] ppStr;

//...

Is it the way to do it ?


By the way, it is not a MFC project. I tried to use (LPCTSTR*)&vs[0] also,
but don't know how to put a NULL at the end.

--
peter lin

Re: std::vector<CString> to LPCTSTR * by Doug

Doug
Sat Aug 20 14:18:34 CDT 2005

On Sun, 21 Aug 2005 02:19:52 +0800, "peter lin" <lxya@yahoo.com> wrote:

>Hi,
>
>I need to call a function, like dummy_fun( LPCTSTR * ppStr ), the ppStr
>parameter's data is stored in a database, so this parameter cannot be
>initialized using syntax like LPCTSTR ppStr[] = {_T("AAA"), ..., NULL }.
>
>Following code is used to retrieve data from database and stored them to a
>vector and construct the ppStr parameter.
>
>//...
>std::vector<CString> vs;
>while ( SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET) {
> DBSTATUS dt;
> rs.GetStatus(_T("ItemText"), &dt);
> if (dt == DBSTATUS_S_OK) {
> CString str((LPCTSTR)rs.GetValue(_T("ItemText")));

You should be able to get rid of the cast here.

> if (!str.IsEmpty()) {
> vs.push_back(str);
> }
> }
> hr = rs.MoveNext();
>}
>
>LPCTSTR *ppStr = new LPCTSTR[vs.size() + 1];
>
>size_t i = 0, vsMax = vs.size();
>while ( i < vsMax) { ppStr[i] = vs[i]; ++i;}

As a style preference, I would have used a for loop here.

>ppStr[vsMax] = NULL; // terminating NULL
>dummy_function( ppStr ); // This function has a LPCTSTR * parameter
>delete[] ppStr;
>
>//...
>
>Is it the way to do it ?

If the code between the new[] and the delete[] could throw, or I didn't
need to eke the last drop of performance out of the code, I would have used
a vector<LPCTSTR>. Other than exception safety, it looks fine.

Note that CString::operator LPCTSTR would let you replace your loop with:

*std::copy(vs.begin(), vs.end(), ppStr) = NULL;

With a vector<LPCTSTR> vStr, you would have needed:

// Size not set in advance
*std::copy(vs.begin(), vs.end(), std::back_inserter(vStr)) = NULL;

// Size set in advance
*std::copy(vs.begin(), vs.end(), &vStr[0]) = NULL;

>By the way, it is not a MFC project. I tried to use (LPCTSTR*)&vs[0] also,
>but don't know how to put a NULL at the end.

Best not to go there. :)

--
Doug Harrison
VC++ MVP

Re: std::vector<CString> to LPCTSTR * by Alex

Alex
Sat Aug 20 15:15:33 CDT 2005

peter lin wrote:
> [...]
> std::vector<CString> vs;
> [...]
> By the way, it is not a MFC project.

If it's not MFC project, the how do intend to use CString?



Re: std::vector<CString> to LPCTSTR * by Carl

Carl
Sat Aug 20 18:05:46 CDT 2005

Alex Blekhman wrote:
> peter lin wrote:
>> [...]
>> std::vector<CString> vs;
>> [...]
>> By the way, it is not a MFC project.
>
> If it's not MFC project, the how do intend to use CString?

It's not necessary to use MFC ot use CString as of VC7 and later.

-cd



Re: std::vector<CString> to LPCTSTR * by peter

peter
Sat Aug 20 21:56:26 CDT 2005


"Doug Harrison [MVP]" <dsh@mvps.org> wrote in message
> With a vector<LPCTSTR> vStr, you would have needed:
>
> // Size not set in advance
> *std::copy(vs.begin(), vs.end(), std::back_inserter(vStr)) = NULL;
>
> // Size set in advance
> *std::copy(vs.begin(), vs.end(), &vStr[0]) = NULL;

That's exactly what I asked! Thanks!

--
Peter Lin