oracle / odpi

ODPI-C: Oracle Database Programming Interface for Drivers and Applications
https://oracle.github.io/odpi/
Other
264 stars 75 forks source link

Encoding of dpiContextCreateParams.oracleClientLibDir and .oracleClientConfigDir #140

Open kubo opened 4 years ago

kubo commented 4 years ago

Both dpiContextCreateParams.oracleClientLibDir and dpiContextCreateParams.oracleClientConfigDir are documented as "A null-terminated UTF-8 encoded string defining the location ...". However I don't think so as far as I looked the source code.

On unix, file systems don't define the encoding of file names. A file name consists of any byte excluding /. When Oracle libraries are in a EUC-JP encoded directory, oracleClientLibDir must be a EUC-JP encoded string even if the locale encoding is UTF-8. Well, I think file name encoding is almost UTF-8 nowadays, though.

On Windows, both must be a null-terminated string encoded by the current Windows ANSI code page, which is CP932 on Japanese-version Windows, CP1252 on English-version Windows. That's because both are passed to ANSI-version functions; LoadLibraryA and SetEnvironmentVariableA respectively. (ODPI-C calls LoadLibrary and SetEnvironmentVariable, which are mapped to ANSI-version.)

// In libloaderapi.h
#ifdef UNICODE
#define LoadLibrary  LoadLibraryW
#else
#define LoadLibrary  LoadLibraryA
#endif // !UNICODE
// In processenv.h
#ifdef UNICODE
#define SetEnvironmentVariable  SetEnvironmentVariableW
#else
#define SetEnvironmentVariable  SetEnvironmentVariableA
#endif // !UNICODE

If this isn't a documentation issue but a bug, Unicode-version functions must be called on Windows.

  1. Convert a UTF-8 encoded string to a wide character string by using MultiByteToWideChar with CP_UTF8.
  2. Pass the wide character string to a Unicode-version function; LoadLibraryW or SetEnvironmentVariableW.
cjbj commented 4 years ago

Thanks @kubo