Синтаксическая ошибка C2059 при использовании макроса declspec для одной функции; отлично компилируется без него

#c #visual-studio #dll

#c #visual-studio #dll

Вопрос:

Я создаю общую библиотеку (кроссплатформенную), но при попытке скомпилировать сборку Windows я сталкиваюсь с ошибкой:

secure_string.h(43): ошибка C2059: синтаксическая ошибка: ‘тип’

Это касается макроса SECURESTRING_API . Он не жалуется на два использования в strlcpy и strlcat, но при попытке использовать его для ‘str_from_last’ он генерирует указанную выше ошибку. Если я удалю его, он отлично компилируется, но функция не экспортируется из DLL, что делает ее совершенно бесполезной!

Поиск в Google не дал (соответствующих) результатов; кто-нибудь сталкивался с этим раньше? Я тестировал как на Visual Studio 2008, так и на 2010, и результат идентичен. Исходный файл включает string.h, а затем этот файл — больше ничего.

Заголовочный файл:

 #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. BOOL Макрос выглядит подозрительно, может быть, он определен для чего-то, что не является типом?

2. К сожалению, нет — он не определен при обработке. Удаление определений показывает, что тип не существует. Я просто заменил все ‘BOOL’ на ‘int’, и вернулась та же ошибка.

Ответ №1:

 #if _WIN32
 

Вы уверены, что вводите это? Я бы:

 #if defined(WIN32)
 

РЕДАКТИРОВАТЬ: это выглядит нормально, но я думаю, что это так:
переместите SECURESTRING_API перед возвращаемым типом (char*):

 SECURESTRING_API char*
 

С этим изменением ваш код компилируется для меня под VS2010, и MSDN подтверждает, что это требуемый порядок:

Decl-specifier-seq должен содержать, среди прочего, базовый тип (например, int, float, typedef или имя класса), класс хранения (например, static, extern) или расширение __declspec . Init-declarator-list должен содержать, среди прочего, указательную часть объявлений.

Комментарии:

1. Он определенно вводит его — в обоих IDE код не выделен серым цветом, а intellisense отображает его как ‘1’. Это и загрузка скомпилированной библиотеки DLL в Dependency Walker показывает две экспортированные функции!

2. Отлично! Поражен, что я никогда не сталкивался с этим за последние годы. Ссылка также полностью исправила это. Приветствия