Wzajemne przywozu
Eksportowanie lub importowanie do innego pliku wykonywalnego przedstawia komplikacje podczas przywozu są wzajemne (lub cykliczne).Na przykład dwa pliki dll zaimportuj symbole od innych, podobnych do wzajemnie funkcji cyklicznej.
Problem z wzajemnie importowanie plików wykonywalnych (zazwyczaj dll) jest mogą być ani wbudowane bez tworzenia innych pierwszej.Każdy proces budowania wymaga jako dane wejściowe, biblioteka przywóz wyprodukowany przez proces budowania.
Rozwiązaniem jest użycie narzędzia LIB z opcją /DEF, który produkuje biblioteki import bez tworzenia pliku wykonywalnego.Narzędzie to można tworzyć biblioteki przywozu konieczne jest, niezależnie od tego, ile biblioteki DLL są zaangażowane lub są skomplikowane jak zależności.
Ogólne rozwiązanie do obsługi wzajemnego przywozu jest:
Z kolei podjęcia każdej biblioteki DLL.(Dowolnego zamówienia jest możliwe, chociaż niektóre zamówienia są bardziej optymalne). Jeśli wszystkie biblioteki import potrzebne istnieją i są aktualne, uruchom łącze, aby zbudować plik wykonywalny (DLL).Daje to biblioteka importu.W przeciwnym razie uruchom LIB produkować biblioteki import.
Uruchomiona LIB z opcją /DEF tworzy dodatkowy plik z.Rozszerzenie EXP..EXP pliku musi być później używana do tworzenia pliku wykonywalnego.
Po użyciu łącza lub LIB budowania biblioteki import, wróć i uruchomić łącze do tworzenia plików wykonywalnych, które nie zostały zbudowane w poprzednim kroku.Należy zauważyć, że odpowiedni plik .exp musi być określony w wierszu łącze.
Po uruchomieniu narzędzia LIB wcześniej produkować biblioteki importu dla DLL1, LIB będzie produkowane pliku DLL1.exp, jak również.Podczas konstruowania DLL1.dlll, należy użyć DLL1.exp jako dane wejściowe do łącza.
Na następującej ilustracji pokazano rozwiązania dla dwóch wzajemnie przywozu biblioteki DLL, DLL1 i DLL2.Krok 1 jest uruchomienie LIB z zestawu opcji /DEF na DLL1.Krok 1 daje DLL1.lib, biblioteka importu i DLL1.exp.W kroku 2 biblioteki import jest używany do tworzenia DLL2, który z kolei produkuje biblioteki import symboli DLL2's.Krok 3 tworzy DLL1, przy użyciu DLL1.exp i DLL2.lib jako danych wejściowych.Należy zauważyć, że plik .exp DLL2 nie jest konieczne, ponieważ LIB nie została wykorzystana do utworzenia biblioteki import DLL2's.
Dwa pliki dll z przywozem wzajemne łączenie
Ograniczenia _AFXEXT
Można użyć _AFXEXT preprocesora symbol swoje rozszerzenie DLL tak długo, jak nie ma wiele warstw z rozszerzeniem dll.Jeśli mają rozszerzenie DLL wywołania lub pochodzić od klasy własne rozszerzenie DLL, które następnie wynikają z klas MFC, należy użyć symbolu preprocesora, aby uniknąć niejednoznaczności.
Problem polega na tym w Win32, musi jawnie deklarować wszelkie dane jako opcję __declspec(dllexport) jeśli mają zostać wywiezione z biblioteki DLL, i __declspec(dllimport) , jeżeli jest przywożone z biblioteki DLL.Podczas definiowania _AFXEXT, nagłówki MFC, upewnij się, że AFX_EXT_CLASS jest poprawnie zdefiniowany.
Gdy masz wiele warstw, jeden symbol takich jak AFX_EXT_CLASS nie jest wystarczające, ponieważ biblioteka DLL rozszerzenia może być eksportowanie nowych klas jak również importowanie innych klas z biblioteki DLL rozszerzenia innej.Aby rozwiązać ten problem, należy użyć specjalnych symboli preprocesora wskazujący budowania DLL sam kontra przy użyciu biblioteki DLL.Załóżmy na przykład, dwa rozszerzenie DLL, A.dll i B.dll.Każdy z nich niektóre klasy A.h i B.h, odpowiednio na wywóz.B.dll korzysta z klas z A.dll.Pliki nagłówków będzie wyglądać następująco:
/* A.H */
#ifdef A_IMPL
#define CLASS_DECL_A __declspec(dllexport)
#else
#define CLASS_DECL_A __declspec(dllimport)
#endif
class CLASS_DECL_A CExampleA : public CObject
{ ... class definition ... };
// B.H
#ifdef B_IMPL
#define CLASS_DECL_B __declspec(dllexport)
#else
#define CLASS_DECL_B __declspec(dllimport)
#endif
class CLASS_DECL_B CExampleB : public CExampleA
{ ... class definition ... };
...
Podczas tworzenia A.dll jest zbudowany z /D A_IMPL i podczas tworzenia B.dll jest zbudowany z /D B_IMPL.Za pomocą oddzielnych symbole dla każdej biblioteki DLL, CExampleB jest eksportowany i CExampleA jest przywożone podczas konstruowania B.dll.CExampleAjest wywożone podczas konstruowania A.dll i przywożone, gdy jest używana przez B.dll (lub innego klienta).
Ten typ warstwy nie można wykonać przy użyciu wbudowanych AFX_EXT_CLASS i _AFXEXT symboli preprocesora.Techniki opisane powyżej rozwiązuje ten problem, w sposób nie w przeciwieństwie do mechanizmu MFC sam używa podczas konstruowania jego Active technologii, bazy danych i biblioteki DLL rozszerzenia sieci.
Eksportowanie nie całej klasy
Nie eksportujesz całej klasy, należy zapewnić prawidłowo wyeksportowane elementy niezbędne dane utworzone przez makra MFC.Można tego dokonać poprzez przedefiniowanie AFX_DATA do określonej klasy makra.Powinno to dowolnym czasie nie eksportujesz całej klasy.
Na przykład:
/* A.H */
#ifdef A_IMPL
#define CLASS_DECL_A _declspec(dllexport)
#else
#define CLASS_DECL_A _declspec(dllimport)
#endif
#undef AFX_DATA
#define AFX_DATA CLASS_DECL_A
class CExampleA : public CObject
{
DECLARE_DYNAMIC()
CLASS_DECL_A int SomeFunction();
//... class definition ...
};
#undef AFX_DATA
#define AFX_DATA
Co chcesz zrobić?
Wywóz z biblioteki DLL przy użyciu opcję __declspec(dllexport)
Funkcje C++ eksportu do użycia w plików wykonywalnych języka c