2016-05-25 5 views
4

Wir haben (fälschlicherweise) StringCbPrintfW verwendet, um eine Datenbankabfrage zu schreiben, die kläglich auf einem Gebietsschema fehlschlägt, das ein Komma als Dezimaltrennzeichen verwendet. Fix ist einfach genug, oder? StringCbPrintf_lW, das ein Gebietsschema verwendet, wird ebenfalls in strsafe.h definiert. Beide sind definiert unter:Locale-bewusste Version der StrSafe-Funktion (StringCbPrintf_lW) kann nicht gefunden werden

#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 

so nur das Gebietsschema erstellen und ersetzen StringCbPrintfW mit StringCbPrintf_lW.

Intellisense ist glücklich, GoToDefinition ist glücklich, ClCompile ist nicht. Ich bekomme ständig

Fehler C3861: 'StringCbPrintf_lW': Bezeichner nicht

gefunden

Irgendwelche Ideen, was falsch ist?

Antwort

5

Der Header Strsafe.h definiert die Methode in Frage, zwei definiert mit dieser Funktion zum Filtern wie folgt:

#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 
// ... 

Kurz gesagt, Sie brauchen STRSAFE_LOCALE_FUNCTIONS zu definieren, bevor Sie den Header enthalten. Wie in:

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

Seltsame Eigenart. Ich kann nur daran denken, Programmierer zu zwingen, die den Funktionsnamen mit einem Großbuchstaben I (Auge) statt einem Kleinbuchstaben l (Ell) buchstabieren, um in der .h Datei zu suchen :) –

+0

#define STRSAFE_LOCALE_FUNCTIONS hat den Trick gemacht. Vielen Dank. Ich habe keine Ahnung wie ich die fehlende Definition vermisst habe. –

+1

Nicht streng verwandt, aber trotzdem gut zu wissen: * "Sie können' STRSAFE_NO_CB_FUNCTIONS' oder 'STRSAFE_NO_CCH_FUNCTIONS' definieren, aber nicht beides." * (Aus [Über Strsafe.h] (https://msdn.microsoft.com/de) -us/library/windows/desktop/ms647466.aspx)). Nicht wirklich eine Überraschung, aber manchmal ist es schön, das Offensichtliche explizit zu formulieren. – IInspectable

1

im Sammler- <strsafe.h> Spelunking, werden Sie feststellen, dass die StringCbPrintf_lW Funktion durch einen Präprozessor #if wie dies bewacht:

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

Also, die aformentioned API aktivieren In Ihrem Code müssen Sie nur das STRSAFE_LOCALE_FUNCTIONS Makro definiert und das STRSAFE_NO_CB_FUNCTIONS Makro nicht definiert.

Mit VS2015 habe ich festgestellt, dass keines dieser beiden Makros standardmäßig definiert ist.
Also, man muss nur #define STRSAFE_LOCALE_FUNCTIONS vor Ihren Kopf einschließlich:

#define STRSAFE_LOCALE_FUNCTIONS 
#include <strsafe.h> 

Man könnte auch, dass Präprozessormakro am gesamten Projektebene definiert das Visual Studio IDE verwenden, folgendermaßen vor: Projekteigenschaften | Konfigurationseigenschaften | C/C++ | Präprozessor und fügen Sie es der Liste in Präprozessor Definitionen.

+0

Nun, es hat wenig Sinn, das Makro projektweit zu definieren. Es muss wirklich nur an der Stelle der Aufnahme des StrSafe-Headers definiert werden. Legen Sie einfach die beiden Zeilen in Ihre vorkompilierte Kopfzeile und fahren Sie fort. –

+0

@CodyGray: Nicht jeder verwendet vorkompilierte Header in ihren Projekten. –

+0

Das stimmt, nehme ich an.In diesem Fall würde ich lieber meinen eigenen "Wrapper" -Header erstellen, der diese beiden Zeilen enthält, und ihn dann überall dort einfügen, wo ich die String-Manipulationsfunktionen brauche. –