Dla jednego z moich projektów: Manga Crawler postanowiłem podczas rozbudowy programu przejść na plikobazę SQLLite. Dostęp do niej zamierzam uzyskać poprzez jakiś ORM (prawdopodobnie NHibernate). Na razie chciałem uruchomić tylko dostęp poprzez ADO z wykorzystaniem System.Data.SQLite.
Jak zawsze staram się wszystko kompilować z źródeł. System.Data.SQLite jest pod tym względem wyjątkowo oporna. W solucji mamy trzy projekty:
SQLite.Interop.2010 - SQLLite + dodatkowy kod odpowiedzialny za rozszerzania, szyfrowanie, i zmienę zachowania pewnych funkcji z uwagi na GC w .NET. Wszystko jest kompilowane w C++.
System.Data.SQLite.2010 - źródła wrappera ADO w C#.
System.Data.SQLite.Module.2010 - dołączona jako moduł do pierwszego. Źródła takie same jak projekt 2. Zmieniane są tylko opcje kompilacji.
Z uwagi na to, że projekt 2 i 3 mają wspólne źródła ktoś wpadł na pomysł, że można części wspólne projektu powyłączać do osobnych plików i dołączać je. Nie jest to zły pomysł, tylko, że VS nie radzi sobie z tym i w explorerze nie ma żadnych plików.
Wszystkie 3 pliki projektów powinniśmy uważnie przestudiować gdyż mają one dużo niewidocznego z GUI kodu.
Moduł 3 dołączany do 1 to tak naprawdę skompilowane źródła (do języka pośredniego), moduły takie mogą się składać na assembly.
Jak to się dzieje, że nasz projekt 1 po dołączeniu 3 staje się assembly (w trybie mixed-mode, który powala na łączenie kodu niezarządzanego i zarządzanego). Cały projekt choć kompilowany jest zwykły projekt C++ ma poustawiane opcje tak, że w rzeczywistości jest mixed mode DLL.
W czym więc problem.
Jako referencje w naszym programie powinniśmy wskazać projekt 1, ale nie zawiera on zarządzanych źródeł z projektów 2 i 3. Tak więc nasze referencje w kodzie nie zostaną rozwiązane. Jeśli wskażemy projekt 2 to podczas uruchomienia dostaniemy błąd. Projekt drugi kompiluje się do System.Data.SQLite.2010.DLL, wykorzystuje natywne funkcje z SQLite.Interop.2010.DLL. Tak więc dostaniemy błąd o braku SQLite.Interop.2010.DLL. Kiedy kod z 2 jako 3 zostanie umieszczony w 1 żadnego błędu nie dostaniemy, wszystko jest w jednej bibliotece i kod zarządzany importuje symbole z niezarządzanej części tej samej DLLki.
Możemy oczywiście dodawać SQLite.Interop.2010.DLL do miejsca gdzie siedzi exe. Musimy to robić w post-build projektu. VS nie pozwala nam dodać referencję do niezarządanego projektu.
Teraz jak to pisze to przychodzi mi na myśl, że być może projekt 1 powinniśmy ustawić na zarządzalny, cały kod objąć klauzulą UNSAFE. Wtedy taki projekt moglibyśmy dodać do projektu z exe.
Jeśli projekt 2 skopiujemy tam gdzie exe w post-build to zawiera on powielony kod z 2. Nie wiem co się stanie jak załadujemy taką dllke, teoretycznie będziemy ją ładować jako niezarządzaną. Takie rozwiązanie wymaga trzech projektów w mojej solucji, których współdziałanie bez analizy będzie wywoływało wiele pytań. Po co 3, po co w dwóch to samo.
Osobiście zdecydowałem się na przerobienie projektów. Projekt 1 zawiera tylko źródła niezarządzalne i dodawany jest do głównego projektu w post-build. Do głównego projektu dodawany jest projekt 2. Nazwa dllki projektu 1 jest taka jakiej poszukuje projekt 2. Przy okazji powłączałem do plików projektów wszystkie includy.
Niby nic ale z uwagi na to jak to wszystko jest poplątane poszedł na to cały dzień. Osobiście nie jestem fanem takiego mieszania w pliku projektu, by mieszać nasz kod z kodem VS. Co najwyżej tu i tam dodać include do naszych elementów i tyle.
Całkiem przyjemną rzeczą byłaby możliwość ustawiania naszych opcji ustawianych w pliku projektu. Jak na razie jedyną możliwością ich zmiany są parametry podczas kompilacji z linii poleceń.
Przy okazji wywaliłem też jakieś bitmapy, zbędne jak mi się wydaje.
Zobaczymy czy będzie działać.
O ile podczas kolejnych wydań nie będą modyfikowane pliki projektów cała aktualizacja na nowy kod powinna przejść gładko.
Pokazywanie postów oznaczonych etykietą SQLite. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą SQLite. Pokaż wszystkie posty
2012-02-10
Subskrybuj:
Posty (Atom)