2009-06-12 16 views
6

Załóżmy, że pracujesz tylko w świecie C++ (interop międzyjęzykowy nie jest wymagany). Jakie zalety/niedogodności widzisz w używaniu COM zamiast zwykłej podstawowej biblioteki DLL? Czy uważasz, że używanie COM jest warte problemów, jeśli nie zamierzasz korzystać z interfejsu z różnych języków?Co jest zaletą korzystania z COM w zwykłym DLL?

Odpowiedz

6

COM może być przydatna w zwykłym starym C++ dla: komunikacji

  • międzyprocesowa
  • Plugin architektur
  • późnego wiązania scenariuszy
  • "wiele, wiele więcej ..." (tm)

To powiedziawszy, jeśli go nie potrzebujesz, nie używaj go.

+5

Tak całkowicie zgadzam się - o ile jest to potrzebne, to często więcej kłopot. – stephbu

+0

Amen. COM i technologie, które się z nim łączyły, stanowiły duży krok naprzód między OLE a miejscem, w którym teraz jesteśmy, ale nie jest to coś, co chcielibyście się wycofać, chyba że nie możecie tego uniknąć. Podstawową trudnością w przypadku COM jest to, że będziesz robił ręcznie rzeczy, które inne rozwiązania rozwiązują w tle. – quillbreaker

1
  • Rejestracja i odkrycie
  • Out-of-process
  • zdalne wywołanie

są kilka dodatkowych funkcji, które masz. Nawet wsparcie transakcyjne może przepływać bez potrzeby wsparcia COM w dzisiejszych czasach.

1

Interfejs IUnknown stanowi dobry poziom bazowy do obsługi w każdym razie - zapewnia sposób dodawania funkcji bez zrywania starych klientów (QueryInterface) i wszechobecnego liczenia odwołań. Możesz to wdrożyć bez kupowania wszystkiego w COM.

Następnie, za każdym razem, gdy dodajesz funkcję do klasy, jeśli używasz do niej interfejsu COM, otrzymujesz przynajmniej znany interfejs - na przykład IDispatch, jeśli chcesz korzystać z funkcji odbicia.

Twoja jedyna delta, która nie będzie mogła być wywołana przez inny język, będzie wtedy rejestracją i fabryką klas.

5

Dzięki DLL możesz uzyskać dużo bliższe sprzężenie, a COM bardzo precyzyjnie interakcje. Jest to podstawa zarówno zalet, jak i wad!

Otrzymujesz większą moc i elastyczność (np. Dziedziczą z klas zdefiniowanych w DLL, niewykonalne w COM), ale zależność jest przez to znacznie silniejsza (trzeba przebudować użytkownika dla niektórych zmian w DLL, itp.).

Często szczególnie kłopotliwe jest to, że wszystkie biblioteki DLL i EXE muszą korzystać z tego samego rodzaju biblioteki uruchomieniowej i opcji (np. Wszystkie dynamicznie połączone z non-debugową wersją wielowątkową msvcrt* na przykład - nie można odbudować tylko jednego do użycia wersja debugowania bez ponoszenia bardzo prawdopodobnych błędów!).

Luźniejsze sprzężenie COM jest często preferowane, chyba że naprawdę potrzebujesz interakcji o ściślejszym sprzężeniu w konkretnym przypadku (np. Szkielet, który zdecydowanie wymaga, aby kod użytkownika dziedziczył z jego klas, powinien być DLL).

1

Ponieważ interfejsy są niezależne od jakiejkolwiek konkretnej biblioteki DLL, na najprostszym poziomie, podejście podobne do COM przynajmniej pozwala na zmianę biblioteki dll obsługującej interfejs pod maską, bez konieczności przekompilowywania aplikacji pod nową nazwą biblioteki dll .

Korzystanie z pełnej wersji COM ze zdefiniowanymi interfejsami MIDL i pośrednimi kodami pośredniczącymi oznacza, że ​​można używać COM do zarządzania bezpieczeństwem wątków wewnątrz procesorów, komunikacji międzyprocesorowej na tym samym komputerze, a nawet do łączenia się z obiektem serwera COM na zdalnym komputerze.

+0

Niezupełnie prawda. Jeśli nie zmienisz definicji funkcji i zmienisz tylko jej implementację, nie będziesz musiał rekompilować swojej aplikacji - tylko DLL. Jeśli zmienisz sygnatury funkcji, będziesz musiał przekompilować, czy korzystasz z prostych bibliotek DLL, czy COM. –

+0

Miałem na myśli. zmiana nazwy biblioteki dll, a nie funkcja. COM oddziela moduły, więc po kilku latach projektowania aplikacji nie jesteś zablokowany do utrzymywania pliku a.dll, b.dll i c.dll.Możesz dowolnie łączyć obiekty COM w większe biblioteki dll lub rozdzielać je bardziej, gdy wymagają tego zmieniające się potrzeby aplikacji. –

8

Każdy wspomina o rzeczach, które są w kolumnie COM plus. Wspomnę o paru naruszeń.

  • Podczas wdrożenia systemu przy użyciu COM, musisz się zarejestrować „Servers” COM (być one-proc lub out-of-proc) w konfiguracji i wyrejestrować je przy deinstalacji. Może to nieco zwiększyć złożoność systemu instalacyjnego i zwykle wymaga ponownego uruchomienia, chyba że użytkownik najpierw zignoruje uruchomione procesy.

  • COM jest powolny w porównaniu do innych standardowych sposobów robienia tego samego. Ten komentarz prawdopodobnie wygeneruje wiele nienawiści, a być może kilka lekceważących, ale faktem jest, że w pewnym momencie będziesz musiał przesłać dane, co jest drogie.

  • Zgodnie z Regułami COM, po opublikowaniu interfejsu, nigdy nie można go zmienić. To samo w sobie nie jest negatywne, a możesz nawet twierdzić, że zmusza Cię do wykonania dokładnego projektu przed wysłaniem interfejsu. Ale prawda jest taka, że ​​nie ma czegoś takiego jak nigdy, aw kodach produkcyjnych zmieniają się interfejsy. Bez wątpienia będziesz musiał dodać metody lub zmienić sygnatury istniejących metod. Aby to osiągnąć, musisz albo złamać reguły COM - które ma złe efekty - albo przestrzegać reguł COM, które są bardziej skomplikowane niż tylko dodanie parametru do funkcji podobnej do tej, jaką posiadasz z prostą biblioteką DLL.

+1

> COM jest powolny w porównaniu ...

2

Jeśli możesz tego uniknąć, nie używaj go. W moim ostatnim projekcie COM wprowadził całkiem sporo ograniczeń w używaniu interfejsów C++. Wyobraź sobie, że nie możesz po prostu przekazać std :: string, ale musisz użyć tablicy znaków. W takim przypadku należy utworzyć ciąg, a następnie skopiować go do tablicy, którą może obsłużyć COM.

Można również używać tylko bardzo ograniczonego zbioru podstawowych typów, mają odlewy i zastrzeżone zarządzanie pamięcią. Nie możesz użyć nowego/usunąć, ale musisz używać własnych funkcji COM.

Nie można również po prostu wyrzucić wyjątku, ale trzeba zainicjować interfejs COM IErrorInfo, który zostanie ponownie wyświetlony na drugim końcu.

Więc jeśli nie potrzebujesz, nie używaj go. To na pewno przykręci twój projekt. I jeśli jest to potrzebne, starają się oceniać innych możliwości międzyoperacyjne: boost :: interprocess, zeroc lód ...

Pozdrowienia,

Ovanes

+1

Oto niespodzianka: jeśli korzystasz z bibliotek DLL, możesz mieć te same problemy z przekazywaniem znaków std :: string. Jedynym sposobem uniknięcia tego jest użycie tego samego kompilatora dla biblioteki DLL i kodu klienta. Dokładniej, ta sama implementacja std :: string. –

+0

Tak, wiem to. Użyliśmy tego samego kompilatora dla wszystkich projektów. Ale opisany problem std :: string również może mieć inny charakter. Kiedy używasz różnych implementacji standardowej biblioteki dla twojego projektu, nawet z tym samym kompilatorem. – ovanes

Powiązane problemy