Комментарии 12
Более правильное (рабочее) решение:
extern «C» __declspec(dllexport) void SomeMethod() {}
А еще более правильное — использовать вместо __declspec(dllexport) макрос, который развернется в __declspec(dllexport)/__declspec(dllimport) на винде в зависимости от того, используется хедер для сборки или линковки библиотеки, или в __attribute__((visibility(«default»))) в gcc
Лично я вообще удивлён, что кто-то пишет такое напрямую, без макроса. По-моему макрос — это уже стандарт де-факто.
Тем не менее, это фактический стандарт. Каким бы костыльным он ни был. Как вы сами заметили — альтернатив-то нет. Тем более меня удивляет его отсутствие, тем более в студии, где наверняка это уже где-нибудь в шаблонах кода прописано.
Ещё 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
без всяких предупреждений и это бесит.
Еще можно добавить про способы упаковки структур. __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
PS речь идет про кросскомпиляцию, очевидно.
Борьба бобра с ослом, или Адаптация MSVC кода под gcc