C2059 syntax error using declspec macro for one fu

2019-08-05 13:15发布

问题:

I've making a shared library (cross-platform), but when trying to compile the Windows build I'm encountering the error:

secure_string.h(43) : error C2059: syntax error : 'type'

This is in regards to the SECURESTRING_API macro. It doesn't complain about the two usages in strlcpy and strlcat, but when trying to use it for 'str_from_last' it generates the above error. If I remove it, it compiles fine, but the function then isn't exported from the DLL, making it quite useless!

A Google search has yielded no (relevant) results; has anyone encountered this before? I've tested on both Visual Studio 2008 and 2010, and the result is identical. The source file includes string.h and then this file - nothing else.

Header file:

#ifndef SECURE_STRING_H
#define SECURE_STRING_H


/* Provide MS Builds with import/export functionality
 * BUILD_SECURE_STRING should be added to project preprocessor macros */
#if _WIN32
#   if defined(BUILD_SECURE_STRING)
#       define SECURESTRING_API __declspec(dllexport)
#   else
#       define SECURESTRING_API __declspec(dllimport)
#   endif
#else
#   define SECURESTRING_API
#endif


/* Windows on the whole, and glibc do not have/support strlc[at|py]
 * This will almost certainly need revision for proper cross-platform checks */
#if _WIN32 || __GLIBC__ || !defined(HAVE_STRLCPY)
    size_t SECURESTRING_API strlcat(char* dst, const char* src, size_t size);
    size_t SECURESTRING_API strlcpy(char* dst, const char* src, size_t size);
#else
#   define HAVE_STRLCPY     1
#endif


/* In case the active project has yet to include headers for 'BOOL' */
#ifndef BOOL
#   define BOOL     int
#   define TRUE     1
#   define FALSE    0
#endif


/*
 | Locates 'search' within 'source', and if found, returns either the
 | character itself, or the character after it if 'return_from_after_found'
 | is TRUE.
 | If it is not found, or any parameter is invalid, a NULL pointer is returned.
 */
char* SECURESTRING_API
    str_from_last(char* source,
                  char search,
                  BOOL return_from_after_found);



#endif  /* SECURE_STRING_H */

回答1:

#if _WIN32

Are you sure you're entering this? I would:

#if defined(WIN32)

EDIT: That looks OK but this I think is it: move the SECURESTRING_API before the return type (char*):

SECURESTRING_API char*

With this change your code compiles for me under VS2010 and MSDN confirms that is the required order:

The decl-specifier-seq should contain, among other things, a base type (e.g. int, float, a typedef, or a class name), a storage class (e.g. static, extern), or the __declspec extension. The init-declarator-list should contain, among other things, the pointer part of declarations.