Michael J.
Michael J.

Reputation: 349

Locale-aware version of StrSafe function (StringCbPrintf_lW) cannot be found

We (mistakenly) used StringCbPrintfW to write a database query which failed miserably on any locale that uses a comma as the decimal separator. Fix is easy enough, right? StringCbPrintf_lW, which takes a locale, is also defined in strsafe.h. Both are defined under:

#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)

so just create the locale and replace StringCbPrintfW with StringCbPrintf_lW.

Intellisense is happy, GoToDefinition is happy, ClCompile is not. I keep getting

error C3861: 'StringCbPrintf_lW': identifier not found

Any ideas what is wrong?

Upvotes: 4

Views: 201

Answers (2)

theB
theB

Reputation: 6738

The header Strsafe.h defines the method in question, using two defines to filter this function as follows:

#if defined(STRSAFE_LOCALE_FUNCTIONS) && !defined(STRSAFE_NO_CB_FUNCTIONS)
/*++

  STDAPI
  StringCbPrintf_l(
  _Out_writes_bytes_(cbDest) _Always_(_Post_z_) LPTSTR  pszDest,
  _In_ size_t  cbDest,
  _In_ _Printf_format_string_params_(2) LPCTSTR pszFormat,
  _In_ locale_t locale,
  ...
  );

  Routine Description:

  This routine is a version of StringCbPrintf that also takes a locale.
  Please see notes for StringCbPrintf above.

  --*/
#ifdef UNICODE

#pragma region Application Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)

#define StringCbPrintf_l    StringCbPrintf_lW
// ...

In short, you need to define STRSAFE_LOCALE_FUNCTIONS before you include the header. As in:

#define STRSAFE_LOCALE_FUNCTIONS
#ifdef STRSAFE_NO_CB_FUNCTIONS
#pragma message("NO CB FUNCTIONS")
#endif
#include <strsafe.h>

Upvotes: 5

Mr.C64
Mr.C64

Reputation: 43004

Spelunking inside the <strsafe.h> header, you will note that the StringCbPrintf_lW function is guarded by a preprocessor #if like this:

#if defined(STRSAFE_LOCALE_FUNCTIONS) && !defined(STRSAFE_NO_CB_FUNCTIONS)

So, to enable the aformentioned API in your code, you just need to have the STRSAFE_LOCALE_FUNCTIONS macro defined and the STRSAFE_NO_CB_FUNCTIONS macro not defined.

With VS2015, I noted that neither of these two macros is defined by default.
So, you just need to #define STRSAFE_LOCALE_FUNCTIONS before including your header:

#define STRSAFE_LOCALE_FUNCTIONS
#include <strsafe.h>

You could also define that preprocessor macro at the whole project level using the Visual Studio IDE, following: Project Properties | Configuration Properties | C/C++ | Preprocessor and add it to the list in Preprocessor Definitions.

Upvotes: 1

Related Questions