Nano Hash - криптовалюты, майнинг, программирование

Проверьте макрос __declspec в препроцессоре

Если у меня есть SOME_MACRO, который определяется как __declspec(dllimport) или __declspec(dllexport), есть ли способ проверить во время компиляции, какой из них используется?

т.е. что-то вроде этого:

#if SOME_MACRO == __declspec(dllimport)
// do something
#else
// do something else
#endif

УПД. Глядя на ответы, которые я получаю, я думаю, мне следует более конкретно указать, зачем мне это нужно.

Я пытаюсь скомпилировать довольно большую стороннюю библиотеку, в которой функция объявлена ​​как dllexport в большинстве частей их кода, где она включена. Однако есть один компонент, в котором это dllimport.

Мне нужно немного изменить объявление для случая dllimport. Переключение между двумя объявлениями не очень простое, это результат довольно глубокого дерева #ifdef инструкций, разбросанных по нескольким файлам. В принципе, я мог бы выкопать эту информацию из этих инструкций, но чтобы убедиться, что я сделал это правильно, мне пришлось бы попытаться скомпилировать всю библиотеку в нескольких разных конфигурациях (каждая компиляция занимает пару часов).

С другой стороны, если бы был простой способ проверить, оценивается ли их SOME_MACRO для импорта или экспорта, я мог бы быстро протестировать это на небольшой программе и безопасно поместить ее в библиотеку.

19.01.2018

  • __declspec - это не макрос, это специальное ключевое слово в компиляторах Visual C++ (и совместимых). 20.01.2018
  • Использовать ту же логику, которая определяет значение SOME_MACRO? 20.01.2018
  • @Someprogrammerdude спасибо за комментарий и извините, что перепутал термины. Тем не менее, я думаю, идея того, что я хочу проверить, должна быть ясной. 20.01.2018
  • @AnonMail в принципе, это вариант. Но эта логика была реализована кем-то другим и довольно сложна, поэтому я надеялся, что может быть простой способ проверить это во время компиляции. 20.01.2018

Ответы:


1

Вы не можете использовать

#if SOME_MACRO == __declspec(dllimport)

__declspec(dllimport) не является допустимым токеном для выражения препроцессора.

Лучше всего использовать другой макрос препроцессора, например:

// Are we building the DLL?
#if defined(BUILD_DLL)
   // Yes, we are.
   #define SOME_MACRO __declspec(dllexport)
#else
   // No. We are using the DLL
   #define SOME_MACRO __declspec(dllimport)
#endif

Теперь вы можете использовать:

#if defined(BUILD_DLL)

для включения условного кода в зависимости от того, создаете ли вы DLL или используете DLL.


Практически говоря, это заканчивается немного более сложным.

  1. Большинство проектов имеют более одной DLL. BUILD_DLL работать не будет. Вам понадобится BUILD_xxx_DLL для каждой сборки DLL. Допустим, у вас есть две библиотеки DLL, утилита и ядро. и приложение, которое зависит от обоих.

  2. Вам также может понадобиться создать статическую библиотеку.

Вам понадобится что-то вроде следующего в каждом общедоступном файле .h библиотеки утилит.

#if defined(BUILD_UTILITY_STATIC)
   #define UTLIITY_EXPORT
#elif defined(BUILD_UTILITY_DLL)
   #define UTLIITY_EXPORT__declspec(dllexport)
#else
   #define UTLIITY_EXPORT__declspec(dllimport)
#endif

Конечно, вам не нужно повторять один и тот же код во множестве файлов .h. Вы создадите файл .h, содержащий вышеуказанное и #include во всех остальных файлах .h.

При сборке утилиты.dll вам нужно будет определить BUILD_UTILITY_DLL и оставить BUILD_UTILITY_STATIC неопределенным.

При сборке utllity.lib (статической библиотеки) вам нужно будет определить BUILD_UTILITY_STATIC и оставить BUILD_UTILITY_DLL неопределенным.

Пользователи утилиты.dll оставят BUILD_UTILITY_STATIC, а также BUILD_UTILITY_DLL неопределенными.

Пользователи утилиты.lib (статическая библиотека) должны будут определить BUILD_UTILITY_STATIC и оставить BUILD_UTILITY_DLL неопределенным.

Вам понадобится аналогичный файл для core.dll и core.lib.

19.01.2018
  • Спасибо за предложение. Эта логика BUILD_DLL в моем случае реализована кем-то другим. И это слишком сложно, поэтому я надеялся, что смогу преобразовать SOME_MACRO в строку, а затем проверить или что-то в этом роде... 20.01.2018
  • @SiLiKhon, звучит многообещающе. Вы можете немного покопаться и найти эквивалент BUILD_DLL. Вы можете использовать этот макрос, чтобы включить свой условный код. 20.01.2018

  • 2

    Макрос назван вами создателем DLL.

    • Вам нужен заголовочный файл, который работает в режиме экспорта или импорта.
    • Файл C/C++ будет использоваться для создания программы, для сборки DLL (экспорт).
    • Другие файлы C/C++ будут использоваться для вызова DLL (функции импорта).

    В файле реализации сборки макрос, который вы называете, определяется до включения заголовка. например

    #define DLLNAME_BUILD_DLL
    #include "dll_header.h"
    

    В шапке, если макрос определен, режим выставлен на экспорт. При использовании DLL макрос не определяется и функции импортируются.

    20.01.2018
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..