Как стать автором
Обновить

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

Более правильное (рабочее) решение:

extern «C» __declspec(dllexport) void SomeMethod() {}

А еще более правильное — использовать вместо __declspec(dllexport) макрос, который развернется в __declspec(dllexport)/__declspec(dllimport) на винде в зависимости от того, используется хедер для сборки или линковки библиотеки, или в __attribute__((visibility(«default»))) в gcc

Лично я вообще удивлён, что кто-то пишет такое напрямую, без макроса. По-моему макрос — это уже стандарт де-факто.

костыль это, ставший «стандартом» в силу отсутствия альтернатив

Тем не менее, это фактический стандарт. Каким бы костыльным он ни был. Как вы сами заметили — альтернатив-то нет. Тем более меня удивляет его отсутствие, тем более в студии, где наверняка это уже где-нибудь в шаблонах кода прописано.

Есть идеи по добавлению: https://stdcpp.ru/proposals/feb5244f-f6a9-4cc0-ae30-f6b549d2d6c9

Ещё MSVC проглатывает отсутствие ключевого слова typename в некоторых случаях, а GCC ругается:


need ‘typename’ before ‘A<T*>::obj’ because ‘A<T*>’ is a dependent scope

Например, есть у нас шаблонный класс:


template<typename T>
class A
{
    typedef SmartPointer<A> Pointer;
};

И мы его используем где-то в шаблонном классе:


template<typename T>
class B
{
    typename A<T>::Pointer m_A; // MSVC не ругается на отсутствие typename
};

MSVC это проглотит без указания typename без всяких предупреждений и это бесит.

То же самое с ключевым словом template в аналогичных ситуациях.

Еще можно добавить про способы упаковки структур. __attribute__ ((packed)) из gcc, не работет в Visual C++, а аналог делается через pragma. Поэтому в нашем проекте пришлось городить что типа вот этого:


#        if defined(_MSC_VER)
/*           __pragma() is specified starting from Visual Studio 2008*/
#            if (_MSC_VER < 1500)
#                error "Unsupport Visual C compiler version. Minimum version is Visual Studio 2008."
#            endif
#            define ATTRIBUTE_PACKED
/*           Enable packing and supress warning C4103: Packing was changed after the inclusion of the header, probably missing #pragma pop */
#            define BEGIN_ATTRIBUTE_PACKED __pragma(pack(push,1)) \
                                           __pragma(warning(disable : 4103))
/*           Disable packing and enable warning C4103 back */
#            define END_ATTRIBUTE_PACKED   __pragma(pack(pop)) \
                                          __pragma(warning(default : 4103))
#            define ATTRIBUTE_SECTION_GCC(x)
#        elif defined (__GNUC__)
#            define BEGIN_ATTRIBUTE_PACKED
#            define END_ATTRIBUTE_PACKED
#            if defined(__clang__)
#                define ATTRIBUTE_PACKED __attribute__ ((packed))
#            else
#                define ATTRIBUTE_PACKED __attribute__ ((gcc_struct,packed))
#            endif
#        endif /* defined(_MSC_VER) */

При это стурктуры потом приходится определять вот таким образом:


    BEGIN_ATTRIBUTE_PACKED

    struct s1 ATTRIBUTE_PACKED {
          ...
    }

    struct s2 ATTRIBUTE_PACKED {
           ...
    }

    END_ATTRIBUTE_PACKED
Разумнее перейти на alignas() из C++11, если, конечно, есть возможность.
к сожалению, не всё так просто. alignas() не позволяет уменьшить выравнивание меньше, чем выравнивание по умолчанию, поэтому добиться с его помощью того же эффекта, что и #pragma pack(push,1) не получится. Более, того, по стандарту new может игнорировать alignas для over-aligned типа (alignof которого выше alignof(std::max_align_t); однако на практике new по умолчанию возвращает память, выровненную по этой планке). В итоге alignas() получается полезен только в очень узком наборе ситуаций.
Скажите, а зачем понадобилось плагин к mt4 компилировать под Linux?
у нас все девелоперское окружение (включая всякие jenkins) работают под линуксом, поэтому изначально данный проект собирался разработчиком на личной машине (что, например, мне неудобно, потому что нужно заводить виртуалку) или на тестовом сервере с МТ4 (тоже боль, потому что через какой нить rdp и автоматизация примерно никакая).

PS речь идет про кросскомпиляцию, очевидно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий