Re: UNICODE support

Igor Korot <[email protected]> Sun, 27 Mar 2016 20:35:16 -0400
Newsgroups gmane.comp.db.unixodbc.devel
Message-ID <CA+FnnTxGqC-wipS6SDNLmTTi=9VC=OxG6xR-HWNfHVHxo0aMTg@mail.gmail.com>
Nick,

On Sat, Mar 26, 2016 at 2:57 PM, Nick Gorham <[email protected]> wrote:
> On 26/03/16 18:00, Igor Korot wrote:
>>
>> Nick,
>>
>> On Sat, Mar 26, 2016 at 1:36 PM, Nick Gorham <[email protected]> wrote:
>>>
>>> On 26/03/16 17:31, Igor Korot wrote:
>>>>
>>>> Hi, Nick,
>>>>
>>>> On Sat, Mar 26, 2016 at 12:58 PM, Nick Gorham <[email protected]> wrote:
>>>>>
>>>>> On 26/03/16 15:10, Igor Korot wrote:
>>>>>>
>>>>>> Hi, (Nick),
>>>>>> Is it enough to do:
>>>>>>
>>>>>> #define UNICODE
>>>>>>
>>>>>> in order to use SQLW-types and functions?
>>>>>>
>>>>>> Or I need to define something else?
>>>>>>
>>>>>> Thank you.
>>>>>> _______________________________________________
>>>>>> unixODBC-dev mailing list
>>>>>> [email protected]
>>>>>> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
>>>>>
>>>>> You should just be able to use them. Whats not working?
>>>>
>>>> Check the following code:
>>>>
>>>> [code]
>>>> /* odbc.c
>>>>
>>>>       testing unixODBC
>>>> */
>>>> #include <stdlib.h>
>>>> #include <stdio.h>
>>>> #include <odbcinst.h>
>>>> #include <sqlext.h>
>>>>
>>>> #define SQL_WCHART_CONVERT
>>>>
>>>> int main(int argc,char *argv[])
>>>> {
>>>>       SQLHENV m_henv;
>>>>       SQLSMALLINT i = 1, attr_ret;
>>>>       SQLWCHAR driverDesc[1024], driverAttributes[256],
>>>> dsn[SQL_MAX_DSN_LENGTH + 1], sqlState[20],
>>>> errMsg[SQL_MAX_MESSAGE_LENGTH], dsnDescr[255];
>>>>       SWORD pcbDSN, pcbDesc;
>>>>       SQLINTEGER nativeError;
>>>>       SQLSMALLINT cbErrorMsg, descriptionLength;
>>>>       SQLUSMALLINT direction = SQL_FETCH_FIRST, direct =
>>>> SQL_FETCH_FIRST;
>>>>
>>>>       RETCODE ret = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HENV,
>>>> &m_henv
>>>> );
>>>>       if( ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO )
>>>>       {
>>>>           printf( "Error allocating handle\r\n" );
>>>>           while( ( ret = SQLGetDiagRecW( SQL_HANDLE_ENV, m_henv, i,
>>>> sqlState, &nativeError, errMsg, sizeof( errMsg ), &cbErrorMsg ) ) ==
>>>> SQL_SUCCESS )
>>>>           {
>>>>               printf( "Error is: %s\r\n", errMsg );
>>>>           }
>>>>           exit( 0 );
>>>>       }
>>>>       else
>>>>       {
>>>>           ret = SQLSetEnvAttr( m_henv, SQL_ATTR_ODBC_VERSION, (void *)
>>>> SQL_OV_ODBC3, 0 );
>>>>           if( ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO )
>>>>           {
>>>>               printf( "Error setting environment\r\n" );
>>>>               while( ( ret = SQLGetDiagRec( SQL_HANDLE_ENV, m_henv, i,
>>>> sqlState, &nativeError, errMsg, sizeof( errMsg ), &cbErrorMsg ) ) ==
>>>> SQL_SUCCESS )
>>>>               {
>>>>                   printf( "Error is: %s\r\n", errMsg );
>>>>               }
>>>>               exit( 0 );
>>>>           }
>>>>           else
>>>>           {
>>>>               while( ( ret = SQLDrivers( m_henv, direction, driverDesc,
>>>> sizeof( driverDesc ) - 1, &descriptionLength, driverAttributes,
>>>> sizeof( driverAttributes ), &attr_ret ) ) == SQL_SUCCESS )
>>>>               {
>>>>                   while( ( ret = SQLDataSources( m_henv, direct, dsn,
>>>> SQL_MAX_DSN_LENGTH, &pcbDSN, dsnDescr, 254, &pcbDesc ) ) ==
>>>> SQL_SUCCESS )
>>>>                   {
>>>>                       printf( "Driver description is %s", driverDesc );
>>>>                       printf( "DSN description is %s", dsnDescr );
>>>>                       direct = SQL_FETCH_NEXT;
>>>>                   }
>>>>                   if( ret != SQL_SUCCESS && ret != SQL_NO_DATA )
>>>>                   {
>>>>                       printf( "Error retrieving Data Source" );
>>>>                       while( ( ret = SQLGetDiagRec( SQL_HANDLE_ENV,
>>>> m_henv, i, sqlState, &nativeError, errMsg, sizeof( errMsg ),
>>>> &cbErrorMsg ) ) == SQL_SUCCESS )
>>>>                       {
>>>>                           printf( "Error is: %s\r\n", errMsg );
>>>>                       }
>>>>                       break;
>>>>                   }
>>>>                   direction = SQL_FETCH_NEXT;
>>>>               }
>>>>           }
>>>>       }
>>>>       return 0;
>>>> }
>>>> [/code]
>>>>
>>>> resulted in:
>>>>
>>>> [code]
>>>> igor@IgorDellGentoo ~ $ gcc -DUNICODE odbctest.cpp -o odbctest -lodbc
>>>> odbctest.cpp: In function 'int main(int, char**)':
>>>> odbctest.cpp:30:48: warning: format '%s' expects argument of type
>>>> 'char*', but argument 2 has type 'SQLWCHAR* {aka short unsigned int*}'
>>>> [-Wformat=]
>>>>                printf( "Error is: %s\r\n", errMsg );
>>>>                                                   ^
>>>> odbctest.cpp:42:52: warning: format '%s' expects argument of type
>>>> 'char*', but argument 2 has type 'SQLWCHAR* {aka short unsigned int*}'
>>>> [-Wformat=]
>>>>                    printf( "Error is: %s\r\n", errMsg );
>>>>                                                       ^
>>>> odbctest.cpp:52:68: warning: format '%s' expects argument of type
>>>> 'char*', but argument 2 has type 'SQLWCHAR* {aka short unsigned int*}'
>>>> [-Wformat=]
>>>>                        printf( "Driver description is %s", driverDesc );
>>>>                                                                       ^
>>>> odbctest.cpp:53:63: warning: format '%s' expects argument of type
>>>> 'char*', but argument 2 has type 'SQLWCHAR* {aka short unsigned int*}'
>>>> [-Wformat=]
>>>>                        printf( "DSN description is %s", dsnDescr );
>>>>                                                                  ^
>>>> odbctest.cpp:61:60: warning: format '%s' expects argument of type
>>>> 'char*', but argument 2 has type 'SQLWCHAR* {aka short unsigned int*}'
>>>> [-Wformat=]
>>>>                            printf( "Error is: %s\r\n", errMsg );
>>>>                                                               ^
>>>> [/code]
>>>>
>>>> Any idea what is going on? And how to fix it?
>>>>
>>>> Thank you.
>>>
>>>
>>> Err, I think the compiler is telling you, You have a array
>>>
>>> SQLWCHAR errMsg[SQL_MAX_MESSAGE_LENGTH]
>>
>> Well I do have "-DUNICODE" passed to the compiler.
>> So SQLWCHAR should not become "unsigned char", but rather "wchar_t".
>>
>> Am I wrong?
>>
>> Thank you.
>
>
> Yes.
>
> SQLWCHAR that ODBC uses is a 16 byte type, wchar_t is normally a 32 byte
> type.
>
> I think you may be thinking of SQLTCHAR that will switch between char and
> SQLWCHAR depending on the flag. But either way, the standard library
> (printf) doesn't know or care, %s = char

Taken from  C:\Program Files (x86)\Microsoft
SDKs\Windows\v7.0A\Include\sqltypes.h(286:

[code]
#ifdef _WCHAR_T_DEFINED
typedef wchar_t SQLWCHAR;
#else
typedef unsigned short SQLWCHAR;
#endif

#ifdef UNICODE
typedef SQLWCHAR        SQLTCHAR;
#else
typedef SQLCHAR         SQLTCHAR;
#endif  /* UNICODE */
[/code]

I presume unixODBC uses the same code, right?

Which means that all I need is to define _WCHAR_T_DEFINED in order for SQLWCHAR
to become wchar_t instead of unsigned short.

Now on  related note, char = %c char* = %s, is it not?
Granted I didn't use plain C for a long time, but I think here I'm right. ;-)

Thank you.

>
>
> --
> Nick
> _______________________________________________
> unixODBC-dev mailing list
> [email protected]
> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
_______________________________________________
unixODBC-dev mailing list
[email protected]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev