UNICODE support

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

UNICODE support

Igor Korot
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
[hidden email]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UNICODE support

Nick Gorham-2
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
> [hidden email]
> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
You should just be able to use them. Whats not working?

--
Nick
_______________________________________________
unixODBC-dev mailing list
[hidden email]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UNICODE support

Igor Korot
Hi, Nick,

On Sat, Mar 26, 2016 at 12:58 PM, Nick Gorham <[hidden email]> 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
>> [hidden email]
>> 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.

>
> --
> Nick
> _______________________________________________
> unixODBC-dev mailing list
> [hidden email]
> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
_______________________________________________
unixODBC-dev mailing list
[hidden email]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UNICODE support

Nick Gorham-2
On 26/03/16 17:31, Igor Korot wrote:

> Hi, Nick,
>
> On Sat, Mar 26, 2016 at 12:58 PM, Nick Gorham <[hidden email]> 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
>>> [hidden email]
>>> 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]

Which is actually

unsigned short errMsg[];

The you are passing this to a

printf( "%s", errMsg );

%s expects a char[] not a short[] so the error.

--
Nick

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

_______________________________________________
unixODBC-dev mailing list
[hidden email]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UNICODE support

Igor Korot
Nick,

On Sat, Mar 26, 2016 at 1:36 PM, Nick Gorham <[hidden email]> wrote:

> On 26/03/16 17:31, Igor Korot wrote:
>>
>> Hi, Nick,
>>
>> On Sat, Mar 26, 2016 at 12:58 PM, Nick Gorham <[hidden email]> 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
>>>> [hidden email]
>>>> 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.

>
> Which is actually
>
> unsigned short errMsg[];
>
> The you are passing this to a
>
> printf( "%s", errMsg );
>
> %s expects a char[] not a short[] so the error.
>
> --
> Nick
>>
>>
>>> --
>>> Nick
>>> _______________________________________________
>>> unixODBC-dev mailing list
>>> [hidden email]
>>> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
>>
>> _______________________________________________
>> unixODBC-dev mailing list
>> [hidden email]
>> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
>
>
> _______________________________________________
> unixODBC-dev mailing list
> [hidden email]
> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
_______________________________________________
unixODBC-dev mailing list
[hidden email]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UNICODE support

Nick Gorham-2
On 26/03/16 18:00, Igor Korot wrote:

> Nick,
>
> On Sat, Mar 26, 2016 at 1:36 PM, Nick Gorham <[hidden email]> wrote:
>> On 26/03/16 17:31, Igor Korot wrote:
>>> Hi, Nick,
>>>
>>> On Sat, Mar 26, 2016 at 12:58 PM, Nick Gorham <[hidden email]> 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
>>>>> [hidden email]
>>>>> 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

--
Nick
_______________________________________________
unixODBC-dev mailing list
[hidden email]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UNICODE support

Igor Korot
Nick,

On Sat, Mar 26, 2016 at 2:57 PM, Nick Gorham <[hidden email]> wrote:

> On 26/03/16 18:00, Igor Korot wrote:
>>
>> Nick,
>>
>> On Sat, Mar 26, 2016 at 1:36 PM, Nick Gorham <[hidden email]> wrote:
>>>
>>> On 26/03/16 17:31, Igor Korot wrote:
>>>>
>>>> Hi, Nick,
>>>>
>>>> On Sat, Mar 26, 2016 at 12:58 PM, Nick Gorham <[hidden email]> 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
>>>>>> [hidden email]
>>>>>> 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
> [hidden email]
> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
_______________________________________________
unixODBC-dev mailing list
[hidden email]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UNICODE support

Nick Gorham-2
On 28/03/16 01:35, Igor Korot wrote:
Nick,

On Sat, Mar 26, 2016 at 2:57 PM, Nick Gorham [hidden email] wrote:
On 26/03/16 18:00, Igor Korot wrote:
Nick,

On Sat, Mar 26, 2016 at 1:36 PM, Nick Gorham [hidden email] wrote:
On 26/03/16 17:31, Igor Korot wrote:
Hi, Nick,

On Sat, Mar 26, 2016 at 12:58 PM, Nick Gorham [hidden email] 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
[hidden email]
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.

Generally, no. To quote "wchar_t is compiler-dependent and therefore not very portable. Using it for Unicode binds a program to the character model of a compiler. Instead, it is often better to define and use dedicated data types."

In most cases outside of Windows wchar_t is a 4 byte type. You can build unixODBC to use 4 byte SQLWCHAR, but you will find it won't work with most drivers out there.

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. ;-)

Yes, I was assuming a shorthand, where %s is char array, I assumed you would know the array part. But the important part of that is that its char, not long, short or int.

--
Nick

_______________________________________________
unixODBC-dev mailing list
[hidden email]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UNICODE support

Igor Korot
Nick,

On Mon, Mar 28, 2016 at 8:22 AM, Nick Gorham <[hidden email]> wrote:

> On 28/03/16 01:35, Igor Korot wrote:
>
> Nick,
>
> On Sat, Mar 26, 2016 at 2:57 PM, Nick Gorham <[hidden email]> wrote:
>
> On 26/03/16 18:00, Igor Korot wrote:
>
> Nick,
>
> On Sat, Mar 26, 2016 at 1:36 PM, Nick Gorham <[hidden email]> wrote:
>
> On 26/03/16 17:31, Igor Korot wrote:
>
> Hi, Nick,
>
> On Sat, Mar 26, 2016 at 12:58 PM, Nick Gorham <[hidden email]> 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
> [hidden email]
> 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.
>
>
> Generally, no. To quote "wchar_t is compiler-dependent and therefore not
> very portable. Using it for Unicode binds a program to the character model
> of a compiler. Instead, it is often better to define and use dedicated data
> types."
>
> In most cases outside of Windows wchar_t is a 4 byte type. You can build
> unixODBC to use 4 byte SQLWCHAR, but you will find it won't work with most
> drivers out there.

OK, so basically what you are saying is: "Its not possible to write a portable
code which uses MS ODBC manager and unixODBC".
Because looking at my code, it looks like _WCHAR_T_DEFINED is defined. ;-)

It would be nice if the Development manual was updated with this info.

>
> 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.
> ;-)
>
>
> Yes, I was assuming a shorthand, where %s is char array, I assumed you would
> know the array part. But the important part of that is that its char, not
> long, short or int.

Yes, but "char *" is just a dynamically allocated array of characters.

Thank you.

>
> --
> Nick
>
> _______________________________________________
> unixODBC-dev mailing list
> [hidden email]
> http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
>
_______________________________________________
unixODBC-dev mailing list
[hidden email]
http://mailman.unixodbc.org/mailman/listinfo/unixodbc-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: UNICODE support

Nick Gorham-2
On 28/03/16 15:57, Igor Korot wrote:
> Nick,
>
>
> OK, so basically what you are saying is: "Its not possible to write a portable
> code which uses MS ODBC manager and unixODBC".
> Because looking at my code, it looks like _WCHAR_T_DEFINED is defined. ;-)
Yes, its perfectly possible, I do it all the time, use SQLWCHAR [],
expect it to be a two or more byte size array value, and treat as such.
What you cant do is expect the standard library to understand it.

>
> It would be nice if the Development manual was updated with this info.
>
>> 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.
>> ;-)
>>
>>
>> Yes, I was assuming a shorthand, where %s is char array, I assumed you would
>> know the array part. But the important part of that is that its char, not
>> long, short or int.
> Yes, but "char *" is just a dynamically allocated array of characters.

Well, its not, its a pointer to a character, not an array, nothing about
dynamic. But whatever, you cant expect %s in printf to understand
anything but characters. (or multiple char sequences if using UTF8).

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