Вопрос об экспорте / импорте DLL и Extern в Windows - PullRequest
5 голосов
/ 17 сентября 2009

Эй, ребята, у меня есть несколько быстрых вопросов по Windows DLL.

В основном я использую ifdefs для обработки dllexport и dllimport, мой вопрос на самом деле касается размещения dllexports и dllimports, а также ключевого слова extern.

Я помещаю dllimports / dllexports в заголовочные файлы, но нужно ли мне помещать dllexport и dllimports в актуальное определение?

А как насчет typedefs?

Я ставлю dllimport / dllexport впереди? как в

dllexport typedef map<string, int> st_map

Также, что касается ключевого слова extern, я видел, что оно используется так:

extern "C" {

dllexport void func1();

}

Я также видел, как он используется так:

extern dllexport func1();

Один включает в себя «С», а другой нет, мой вопрос, в чем разница, и мне нужно его использовать? Если я это сделаю, то буду ли я использовать его как для dllexport, так и для dllimport, а также должен ли я использовать его как для объявлений файла заголовка, так и для определений?

Мой проект будет общей библиотекой, он содержит несколько файлов классов, которые я хочу экспортировать, некоторые typdefs, которые я хочу экспортировать, и некоторые глобальные функции, которые я также хочу экспортировать все в dll.

Кто-нибудь просветит меня, пожалуйста?

EDIT:

Хорошо, я подумал, что опубликую небольшой фрагмент того, что я сделал, также обратите внимание, что я собираю библиотеку для Linux и Windows, поэтому я проверяю это:

mydll.h

#ifdef WINDOWS
#   ifdef PSTRUCT_EXPORT
#   define WINLIB __declspec(dllexport)
#   else
#   define WINLIB __declspec(dllimport)
#   endif
#else
#  define WINLIB
#endif

WINLIB void funct1();

Теперь в исходном коде:

mydll.cpp

#define PSTRUCT_EXPORT

void funct1() <---- do i need to add WINLIB in front of it? 
                      Or is doing it in the header enough?

Ответы [ 2 ]

7 голосов
/ 17 сентября 2009

Во-первых, вам не нужно импортировать или экспортировать typedefs. Пока они в заголовочных файлах, которые используют обе стороны, у вас все хорошо. Вам нужно импортировать / экспортировать функции и определения классов.

Предположительно, вы используете одинаковые заголовочные файлы как для импорта, так и для экспорта кода, так что вы можете использовать магию make-файла для определения макроса препроцессора на каждой стороне, а затем сделать что-то вроде этого:

#if defined( LIBRARY_CODE )
#define MYAPI __declspec(dllexport)
#else
#define MYAPI __declspec(dllimport)
#endif

extern MYAPI void func1();
class MYAPI MyClass {
    ...
};

Что касается функций C и C ++, вы можете сделать это:

#if defined( __cplusplus__ ) // always defined by C++ compilers, never by C
#define _croutine "C"
#else
#define _croutine
#endif

extern _croutine void function_with_c_linkage();

Убедитесь, что вы импортируете этот заголовочный файл из исходного файла C ++ (содержащего реализацию этой функции), иначе компилятор не узнает, как связать его с C.

2 голосов
/ 17 сентября 2009
  1. typedefs НЕ нужен dllimport / dllexport, это просто определение
  2. dllimport / dllexport не являются стандартными, подумайте об определении макроса для других платформ / компиляторов
  3. также позаботьтесь о соглашении о вызовах (cdecl, stdcall, ...), используемом в противном случае вы столкнетесь с проблемами (если вам необходимо взаимодействие с Visual Basic, используйте stdcall)
  4. заключите во внешнюю "C", чтобы ваша библиотека могла использоваться из программ на C ++, используйте #ifdef __cplusplus, чтобы она оставалась видимой только для C ++.

Посмотрите на разные библиотеки OpenSource. Там вы найдете множество примеров того, как сделать хороший заголовок библиотеки. Могут быть проблемы с оформлением имени в случае C ++ без внешнего "C".

...