2015-08-17 8 views
26

Mój projekt (jakiś rodzaj silnika przetwarzania) jest podzielony na 2 biblioteki dll: jeden z deklaracjami interfejsów i jeden z funkcjonalności. Zwykle projekt jest używany przez zewnętrzny projekt Delphi za pośrednictwem technologii COM.Jak sprawić, by moja biblioteka dll była ładowalna tylko z kodu?

Powiedzmy, że mój program wycina owoce. Zewnętrzny program delphi tworzy obiekt Fruit i wypełnia jego właściwości: weight (int), Name (string) i ProgressUpdater (typu IProgressUpdater, który jest zadeklarowany w drugim dll z interfejsami). Po tym programie exst programator fragmentatora, tworzy Slicer.AddFruit (newFruit) i wywołuje funkcję Slicer.Slice().

Nic specjalnego. W prawdziwym życiu projekt delphi jest dodatkiem do Outlooka. Ale tutaj jest problem - czasami niektóre dodatki VSTO sprawiają, że Outlook działa w trybie "shadow copy files", więc gdy projekt delphi rozpocznie się i zacznie kreślić obiekt Slicer, nasz C# assembly zostanie umieszczony w folderze temp, a montaż zostanie utworzony za pomocą tej lokalnej ścieżki. Cóż ... to nadal nie jest problem. Ale problem polega na tym, że kiedy projekt delphi tworzy newFruit, a następnie przekazuje obiekt ProgressUpdater, w moim zespole fragmentatora nie mogę uzyskać zewnętrznego ProgressUpdater: "Argument return ma nieprawidłowy typ", ale nadal może uzyskać pole z typami prostymi (Weight, Name).

Dzieje się tak tylko przy włączonym trybie shadowCopyFiles. Zgaduję więc - zewnętrzny montaż ProgressUpdater i montaż fragmentatora są umieszczane w różnych miejscach, więc nie można ich przekazać. Moje pytanie brzmi: jak uniknąć tego, że moja biblioteka dll będzie "shadow copied"? Czy jest jakieś inne rozwiązanie?

+1

Nie znam się dobrze na technologii COM, ale czy z zestawu GAC nie należy łączyć zestawów? Podobnie jak [tutaj] (http://edn.embarcadero.com/article/32754) – netaholic

+1

Hmm, jesteś ofiarą wątpliwych praktyk innego dodatku. Niewiele można z tym zrobić, jeśli nie masz numeru telefonu. Ale jedna rzecz, użyj GAC. Zawsze dobrym pomysłem podczas pisania złożeń ComVisible. –

+0

@HansPassant Problem polega na tym, że mój zespół jest już zarejestrowany w GAC. Ale w jednym przypadku Assembly.GetExecutingAssembly(). Lokalizacja; pokazuje ścieżkę kodu źródłowego (ścieżkę, w której została zarejestrowana z regasmem dla współdziałania COM). ale w innym (po tym dodatku VSTO) - pewna ścieżka temp na dysku systemowym. Myślę, że nie będę miał takiego problemu, jeśli będę mógł zmusić .net do załadowania mojego zestawu tylko ze ścieżki kodu. – Shelest

Odpowiedz

1

W rezultacie wciąż nie mam odpowiedzi na dokładne pytanie. Ale problem został rozwiązany (dzięki HansPassant) za pomocą GAC, ponieważ złożeń w GAC nigdy nie będzie kopiowane w tle (faktycznie linker zawsze będzie najpierw sondował złoenia w GAC, a następnie w innych miejscach).

Ewentualną odpowiedzią na pytanie jest przejście do metody currentDomain.AssemblyResolve, ale nie mogłem zastosować tego rozwiązania do biblioteki dll, która zawiera tylko publiczne interfejsy (typy). Być może będzie to odpowiednie rozwiązanie w niektórych przypadkach.

1

Możesz użyć odbicie, aby załadować DLL dynamicznie z dowolnej lokalizacji. Jeśli możesz pójść tą drogą, mogę podać dodatkowy kod do ładowania bibliotek DLL.

+0

Tak, proszę podać przykład. Moja sytuacja jest taka, że ​​moja biblioteka dll zawiera tylko interfejsy (bez metod) i będzie używana przez Delphi przez COM. Więc w jaki sposób mogę zagwarantować, że kiedy facet na Delphi zakończy działanie MyComDll.IProgressUpdater, będzie to ładowanie z codebase? – Shelest

+0

@Slelest, aby załadować zespół przez odbicie, możesz zrobić coś takiego: Assembly.Load (File.ReadAllBytes (path)) - tylko raz przed pierwszym wywołaniem. Możesz również sprawdzić mój artykuł: http://wojciechkulik.pl/csharp/embedded-class-libraries-dll (chodzi o coś innego, ale może jakaś jego część będzie przydatna). –

Powiązane problemy