From: hamishd on
On Jan 8, 12:31 pm, "David Webber" <d...(a)musical-dot-demon-dot-co.uk>
wrote:
> "hamishd" <Hamish.D...(a)gmail.com> wrote in message
>
> news:dc1f26c5-6e3e-435a-9219-af0c908f09de(a)s9g2000prg.googlegroups.com...
>
>
>
> > Hi - sorry this is my 3rd question recently. I'm having trouble with
> > strings and characters and unicode in general; can anybody suggest a
> > good article to read which explains the basics?
>
> > My project is _UNICODE defined. However, a file I got from codeproject
> > is not. Their code is below, but it cannot compile.
>
> > char szBuf[2001];
> > WORD cbBufMax = 2000;
> > WORD cbBufOut;
> > char *pszBuf = szBuf;
>
> > SQLGetInstalledDrivers(szBuf,cbBufMax,& cbBufOut);
>
> > I would have thought changing the char's to TCHAR's would fix..
> > however, I still get "error C2664: 'SQLGetInstalledDriversW' : cannot
> > convert parameter 1 from 'char [2001]' to 'unsigned short *'"
>
> If you have TCHAR szBuf[2001] this should not happen.
>
> In a UNICODE build TCHAR is WCHAR and teh function call is to SQL...W(..)
> In a non-UNICODE build it is CHAR and SQL....A().
>
> Are you sure you have used TCHAR consistently?

This is the entire function:

// Get the name of the Excel-ODBC driver
void CSpreadSheet::GetExcelDriver()
{
char szBuf[2001];
WORD cbBufMax = 2000;
WORD cbBufOut;
char *pszBuf = szBuf;

// Get the names of the installed drivers ("odbcinst.h" has to be
included )
if(!SQLGetInstalledDrivers(szBuf,cbBufMax,& cbBufOut))
{
m_sExcelDriver = "";
}

// Search for the driver...
do
{
if( strstr( pszBuf, "Excel" ) != 0 )
{
// Found !
m_sExcelDriver = CString( pszBuf );
break;
}
pszBuf = strchr( pszBuf, '\0' ) + 1;
}
while( pszBuf[1] != '\0' );
}

The error message is the same regardless of whether or not i use
TCHAR, WCHAR, or char.

From: Joseph M. Newcomer on
See below...
On Wed, 7 Jan 2009 15:19:17 -0800 (PST), hamishd <Hamish.Dean(a)gmail.com> wrote:

>Hi - sorry this is my 3rd question recently. I'm having trouble with
>strings and characters and unicode in general; can anybody suggest a
>good article to read which explains the basics?
>
>My project is _UNICODE defined. However, a file I got from codeproject
>is not. Their code is below, but it cannot compile.
>
> char szBuf[2001];
> WORD cbBufMax = 2000;
> WORD cbBufOut;
> char *pszBuf = szBuf;
>
> SQLGetInstalledDrivers(szBuf,cbBufMax,& cbBufOut);
>
>I would have thought changing the char's to TCHAR's would fix..
>however, I still get "error C2664: 'SQLGetInstalledDriversW' : cannot
>convert parameter 1 from 'char [2001]' to 'unsigned short *'"
****
Note that there are TWO symbols required: _UNICODE and UNICODE (without the _). BOTH
need to be defined, or BOTH need to be not defined. If you only define _UNICODE, half of
your interfaces will be wrong.
joe
****
>
>Incidentally, I am trying to read data from an excel spreadsheet, and
>trying the CSpreadSheet class from http://www.codeproject.com/KB/database/cspreadsheet.aspx.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
I checked the header files; the documentation is wrong, and will shortly be added to my
list of documentation errors.
joe

On Wed, 7 Jan 2009 15:57:14 -0800, "Tom Serface" <tom(a)nospam.camaswood.com> wrote:

>The help for SQLGetInstalledDrivers says:
>
>BOOL SQLGetInstalledDrivers(
> LPSTR lpszBuf,
> WORD cbBufMax,
> WORD * pcbBufOut);
>
>Indicating that you have to use a char buffer, but it looks like it's
>calling a W flavor which seems odd.... Even the error you're getting
>doesn't make sense because the first You might try something like:
>
> TCHAR szBuf[2001];
> WORD cbBufMax = 2000 * sizeof(TCHAR);
> WORD cbBufOut;
> LPTSTR *pszBuf = szBuf; // Not sure what you're using this for exactly
>maybe you intended to pass this into the function instead?
>
>This link might have something useful for you. I admit I haven't used this
>function so I'm sort of just guessing here.
>
>http://bugs.mysql.com/bug.php?id=35776
>
>Tom
>
>
>"hamishd" <Hamish.Dean(a)gmail.com> wrote in message
>news:dc1f26c5-6e3e-435a-9219-af0c908f09de(a)s9g2000prg.googlegroups.com...
>> Hi - sorry this is my 3rd question recently. I'm having trouble with
>> strings and characters and unicode in general; can anybody suggest a
>> good article to read which explains the basics?
>>
>> My project is _UNICODE defined. However, a file I got from codeproject
>> is not. Their code is below, but it cannot compile.
>>
>> char szBuf[2001];
>> WORD cbBufMax = 2000;
>> WORD cbBufOut;
>> char *pszBuf = szBuf;
>>
>> SQLGetInstalledDrivers(szBuf,cbBufMax,& cbBufOut);
>>
>> I would have thought changing the char's to TCHAR's would fix..
>> however, I still get "error C2664: 'SQLGetInstalledDriversW' : cannot
>> convert parameter 1 from 'char [2001]' to 'unsigned short *'"
>>
>> Incidentally, I am trying to read data from an excel spreadsheet, and
>> trying the CSpreadSheet class from
>> http://www.codeproject.com/KB/database/cspreadsheet.aspx.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
See below...
On Wed, 7 Jan 2009 16:22:20 -0800 (PST), hamishd <Hamish.Dean(a)gmail.com> wrote:

>On Jan 8, 12:31�pm, "David Webber" <d...(a)musical-dot-demon-dot-co.uk>
>wrote:
>> "hamishd" <Hamish.D...(a)gmail.com> wrote in message
>>
>> news:dc1f26c5-6e3e-435a-9219-af0c908f09de(a)s9g2000prg.googlegroups.com...
>>
>>
>>
>> > Hi - sorry this is my 3rd question recently. I'm having trouble with
>> > strings and characters and unicode in general; can anybody suggest a
>> > good article to read which explains the basics?
>>
>> > My project is _UNICODE defined. However, a file I got from codeproject
>> > is not. Their code is below, but it cannot compile.
>>
>> > char szBuf[2001];
>> > WORD cbBufMax = 2000;
>> > WORD cbBufOut;
>> > char *pszBuf = szBuf;
>>
>> > SQLGetInstalledDrivers(szBuf,cbBufMax,& cbBufOut);
>>
>> > I would have thought changing the char's to TCHAR's would fix..
>> > however, I still get "error C2664: 'SQLGetInstalledDriversW' : cannot
>> > convert parameter 1 from 'char [2001]' to 'unsigned short *'"
>>
>> If you have TCHAR szBuf[2001] this should not happen.
>>
>> In a UNICODE build TCHAR is WCHAR and teh function call is to SQL...W(..)
>> In a non-UNICODE build it is CHAR and SQL....A().
>>
>> Are you sure you have used TCHAR consistently?
>
>This is the entire function:
>
>// Get the name of the Excel-ODBC driver
>void CSpreadSheet::GetExcelDriver()
>{
> char szBuf[2001];
> WORD cbBufMax = 2000;
> WORD cbBufOut;
> char *pszBuf = szBuf;
****
Apparently due to terminal brain damage on the part of the documentation team, the
documentation specifies this as an LPSTR, and it should be an LPTSTR.

Also, weirdly, it uses a WORD to define the length. Didn't anyone in the SQL group read
that Win32 is now out?
****
>
> // Get the names of the installed drivers ("odbcinst.h" has to be
>included )
> if(!SQLGetInstalledDrivers(szBuf,cbBufMax,& cbBufOut))
> {
> m_sExcelDriver = "";
> }
>
> // Search for the driver...
> do
> {
> if( strstr( pszBuf, "Excel" ) != 0 )
****
For a Unicode app, this should be _tcsstr, comparing to _T("Excel"), and strictly speaking
this should be compared to NULL
****
> {
> // Found !
> m_sExcelDriver = CString( pszBuf );
> break;
> }
> pszBuf = strchr( pszBuf, '\0' ) + 1;
****
A more serious question is why you have chosen random numbers like 2001, 2000, etc.

To handle this correctly, you would typically do something like

WORD buflen = START_BUF_LEN;
CString drivers;
m_sExcelDriver.Empty();

while(TRUE)
{ /* get list of drivers */
WORD cbBufMax = buflen;
LPTSTR szBuf = drivers.GetBuffer(buflen);
if(!SQLGetInstalledDrivers(szBuf, buflen, &cbBufMax))
{
drivers.ReleaseBuffer();

return;
}

if(cbBufMax == buflen - 1)
{ /* was truncated */
buflen *= 2;
continue;
} /* was truncated */
drivers.ReleaseBuffer();
break;
} /* get list of drivers */

Assuming that any randomly-chosen value will be correct is not safe. The above loop is
the standard pattern for an API that can truncate without giving an error.

// Now a more serious question is whether or not there can be multiple drivers
// that contain the word "Excel", but I'm assuming you will accept the first one

LPTSTR szBuf = drivers.GetBuffer();
while(_tcslen(szBuf) > 0)
{ /* scan buffer */
if(_tcsstr(szBuf, _T("Excel") != NULL)
{ /* found one */
m_sExcelDriver = CString(szBuf);
break;
} /* found one */
szBuf += _tcslen(szBuf);
} /* scan buffer */
drivers.ReleaseBuffer();
}

****
> }
> while( pszBuf[1] != '\0' );
****
It is not clear why there is a while-condition here...just test the string length as shown
above.
joe
****
>}
>
>The error message is the same regardless of whether or not i use
>TCHAR, WCHAR, or char.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: hamishd on
On Jan 8, 1:55 pm, Joseph M. Newcomer <newco...(a)flounder.com> wrote:
> See below...
>
>
>
> On Wed, 7 Jan 2009 15:19:17 -0800 (PST), hamishd <Hamish.D...(a)gmail.com> wrote:
> >Hi - sorry this is my 3rd question recently. I'm having trouble with
> >strings and characters and unicode in general; can anybody suggest a
> >good article to read which explains the basics?
>
> >My project is _UNICODE defined. However, a file I got from codeproject
> >is not. Their code is below, but it cannot compile.
>
> >    char szBuf[2001];
> >    WORD cbBufMax = 2000;
> >    WORD cbBufOut;
> >    char *pszBuf = szBuf;
>
> >    SQLGetInstalledDrivers(szBuf,cbBufMax,& cbBufOut);
>
> >I would have thought changing the char's to TCHAR's would fix..
> >however, I still get "error C2664: 'SQLGetInstalledDriversW' : cannot
> >convert parameter 1 from 'char [2001]' to 'unsigned short *'"
>
> ****
> Note that there are TWO symbols required:  _UNICODE and UNICODE (without the _).  BOTH
> need to be defined, or BOTH need to be not defined.  If you only define _UNICODE, half of
> your interfaces will be wrong.

Thanks Joe.