2009-09-17 10 views
5

Hej, mam kilka szybkich pytań na temat biblioteki dll.Pytanie dotyczące eksportowania/importowania DLL i eksternacji na Windows

Zasadniczo używam ifdefs do obsługi dllexport i dllimport, moje pytanie dotyczy w rzeczywistości umieszczenia dllexports i dllimports, a także zewnętrznego słowa kluczowego.

Umieszczam plik dllimports/dllexports w plikach nagłówkowych, ale czy muszę wstawiać dllexport i dllimports do rzeczywistej definicji?

Co powiesz na typedefs?

Czy umieszczam dllimport/dllexport z przodu? jak w

dllexport typedef map<string, int> st_map 

dotyczące Również extern słowa kluczowego Widziałem to wykorzystywane tak:

extern "C" { 

dllexport void func1(); 

} 

Widziałem także może zostać wykorzystane tak:

extern dllexport func1(); 

Jeden zawiera "C", a drugi nie, moje pytanie brzmi: jaka jest różnica i czy muszę z niej korzystać? Jeśli tak, to czy używam go zarówno dla dllexport, jak i dllimport, czy też muszę go używać zarówno w deklaracjach plików nagłówkowych, jak i definicjach?

Mój projekt będzie biblioteką współdzieloną, zawiera kilka plików klas, które chcę eksportować, niektóre pliki do publikacji, które chcę eksportować i niektóre funkcje globalne, które również chcę wyeksportować do biblioteki dll.

Czy ktoś mnie oświeci, proszę?

EDIT:

Dobrze myślałem, że będę pisać mały wyciąg, co zrobiłem, również zauważyć, że buduję bibliotekę zarówno dla linux i windows tak zrobić czek na to:

mydll.h 

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

WINLIB void funct1(); 

teraz w kodzie źródłowym:

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? 

Odpowiedz

7

Po pierwsze, nie trzeba importować ani eksportować maszyn. Dopóki są w plikach nagłówkowych, których używają obie strony, jesteś dobry. Musisz zaimportować/wyeksportować funkcje i definicje klas.

Prawdopodobnie używasz tych samych plików nagłówka zarówno dla importu i kodu wywozu, więc można zrobić kilka makefile magię zdefiniować preprocesora makro z każdej strony, a następnie zrobić coś takiego:

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

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

Odnośnie C w porównaniu z funkcji C++, można to zrobić:

#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(); 

Upewnij się, że import tego pliku nagłówka z C++ pliku źródłowego (zawierającego realizację tej funkcji) lub kompilator nie będzie wiedział, aby nadać mu C powiązania.

+0

Dobra, mam coś bardzo podobnego, z wyjątkiem zewnętrznego słowa kluczowego. Mam podobne makra zdefiniowane we wszystkich plikach klas. Tak więc nazwa zewnętrzna służy do obsługi kompilatorów języka C? Mój projekt jest głównie C++ –

+0

Czy muszę również dodać instrukcje dllimport/export w definicji? –

+0

Jedynym powodem, dla którego potrzebujesz zewnętrznego "C", jest próba połączenia funkcji C++ z kodu C. Zasadniczo możesz zignorować zewnętrzne "C", dopóki nie uzyskasz błędów linkera. –

2
  1. typedefs nie potrzebują dllimport/dllexport, to tylko definicja
  2. dllimport/dllexport nie są standardem, pomyśl o zdefiniowaniu makra dla innych platform/kompilatorów
  3. również zajmij się konwencją wywołania (cdecl, stdcall, ...) używaną w przeciwnym razie napotkasz problemy (jeśli muszą być interoperacyjne z Visual podstawowego użycia stdcall)
  4. zamknij w zewnętrznym "C", aby Twoja biblioteka mogła być używana z programów C++, użyj #ifdef __cplusplus, aby była widoczna tylko dla C++.

Zobacz różne biblioteki OpenSource. Znajdziesz tam mnóstwo przykładów na to, jak zrobić dobry nagłówek biblioteki. W przypadku C++ mogą wystąpić problemy z dekorowaniem nazw bez zewnętrznego "C".

+0

Większość rzeczy, które umieszczam w bibliotece dll są klasami, więc głównie chcę, aby to było kompilowane głównie w C++, więc czy powinienem unikać zewnętrznego "c"? –

+0

W tym przypadku tak - nie wolno używać zewnętrznego "C". Miej jednak świadomość, że z powodu dekoracji nazwy zmuszasz innych do używania tego samego kompilatora do korzystania z twojej biblioteki. Aby tego uniknąć, możesz udostępnić bibliotekę C i opakowanie C++, które można zintegrować jako kod źródłowy w projektach klienta. – jdehaan

Powiązane problemy