2013-03-26 8 views
10

Co to jest najlepsza praktyka dodawania lub modyfikowania metody pojedynczej klasy w dobrze znanej bibliotece C++, takiej jak OpenCV, przy jednoczesnym ponownym wykorzystaniu pozostałej części biblioteki kod, najlepiej w formacie lib.Najlepsza praktyka do częściowej zmiany biblioteki C++ przy zachowaniu nienaruszonej reszty biblioteki

W tym momencie jedynym sposobem, jaki znam, jest skopiowanie wszystkich plików źródłowych i nagłówkowych należących do konkretnej biblioteki (powiedzmy biblioteki głównej OpenCV) do bieżącego folderu źródłowego, zmodyfikowanie tej jednej funkcji i ponowne skompilowanie modułu za pomocą reszta kodu. Idealnie, chciałbym móc połączyć wszystkie obecne pliki .lib takimi, jakie są, ale po prostu zdefiniować nową metodę (lub zmodyfikować bieżącą metodę) dla klasy zdefiniowanej w tych bibliotekach w taki sposób, że moja implementacja metody zastępuje implementacja domyślnych plików bibliotecznych.

Dziedziczenie nie zawsze wydaje się być opcją, ponieważ czasami klasa podstawowa ma członków prywatnych, które są wymagane do prawidłowej implementacji dziedziczonej klasy.

Odpowiedz

7

Nie jestem świadomy czystej drogi w C++, aby osiągnąć to, o co prosisz. To, o co tak naprawdę prosisz (biorąc pod uwagę, że musisz używać lub modyfikować prywatne metody) narusza hermetyzację, a język C++ został zaprojektowany, aby nie pozwolić ci na to. istnieje

Kilka opcji:

  • .lib plik jest po prostu zbiorem .obj plików. Twój zestaw narzędzi kompilatora powinien mieć program wiersza poleceń do dodawania, usuwania i zastępowania plików .obj w .lib, abyś mógł zbudować jeden lub dwa pliki .obj i połączyć je w .lib. Podejrzewam, że to rozwiązanie byłoby brzydkie i kruche.
  • Jeśli jest coś, czego biblioteka nie robi i powinna zrobić, zawsze istnieje szansa, że ​​możesz przesłać poprawkę lub prośbę o dodanie funkcji do autorów bibliotek, aby uzyskać tę zmianę. Oczywiście może to trochę potrwać, jeśli w ogóle działa.
  • Jak sugeruje @fatih_k, dodawanie zmian jako klas znajomych działałoby. Jeśli zmiana w OpenCV nadokona się w celu dodania do pliku nagłówkowego linii friend, biblioteka ABI biblioteki pozostanie niezmieniona, a użytkownik nie będzie musiał dotykać .lib.
  • Najczystszą opcją jest po prostu zaakceptowanie konieczności modyfikacji biblioteki OpenCV i śledzenia kodu źródłowego wraz z modyfikacjami wraz z kodem źródłowym, który sam tworzysz, i budowanie go wraz z kodem źródłowym, który sam tworzysz. Jest to bardzo powszechne podejście i istnieją różne wzorce i techniki, które pomogą ci to zrobić; na przykład Subversion ma koncepcję vendor branches. To podejście wymaga więcej pracy, ale na dłuższą metę jest zdecydowanie najczystsze.
+0

Doskonałe punkty. Zdecydowanie wiele się nauczyłem czytając ten post. Dzięki. – Bee

1

Cóż, OpenCV jest licencjonowany w ramach BSD, dzięki czemu można wprowadzać zmiany bez obawy o ich ponowne opublikowanie.

Zawsze można postępować zgodnie ze wzorcem Proxy i dodawać nową metodę zewnętrzną do biblioteki, a następnie wywoływać w bibliotece. Oznacza to, że nie musisz martwić się o utrzymanie swojej własnej wersji OpenCV i dystrybucję. There's more information about Proxy patterns on Wiki, aby zacząć.

+0

Dzięki za odpowiedź. Niestety projekt proxy nie rozwiązuje problemu z dostępem prywatnych członków. W szczególności chcę zmodyfikować bieżącą metodę klasy w OpenCV, aby obsłużyć wewnętrznych (czasem prywatnych) członków w inny sposób. Proxy pozwala mi na dodatkowe wstępne przetwarzanie, ale podstawowa logika prawdziwej klasy pozostaje taka sama. – Bee

+0

Ah przepraszam, nie zdawałem sobie sprawy, że próbujesz zmodyfikować prywatne dane członków. –

2

Jeśli biblioteka jest już skompilowana, niewiele można zrobić przenośnie i czysto.

Jeśli znasz konkretną docelową architekturę, program będzie działał, możesz dostać wskaźnik do funkcji elementu i małpa załatać instrukcje z instrukcją jmp do swojej własnej wersji metody. Jeśli metoda jest wirtualna, możesz zmodyfikować tabelę vtable. Te wymagają dużej wiedzy o kompilatorach i nie będą przenośne.

Jeśli biblioteka jest dostarczana w archiwum dynamicznych linków, można wyodrębnić archiwum i zastąpić metodę własną wersją, a następnie zapakować archiwum.

Inną metodą jest skopiowanie deklaracji klasy z nagłówka i dodanie deklaracji znajomego. Ewentualnie możesz zrobić #define private public lub #define private protected przed dołączeniem pliku nagłówkowego. Dzięki temu uzyskasz dostęp do swoich prywatnych członków.

W którymkolwiek z powyższych przypadków należy uważać, aby zmiany nie zmieniały ABI biblioteki.

+0

Dzięki! Ciekawe i pomocne pomysły, choć trochę za dużo dla tego konkretnego zadania. OpenCV jest open source i pierwotnie skompilowałem źródło do ich odpowiednich bibliotek, więc edycja źródła biblioteki nie stanowi problemu. Próbowałem tylko zobaczyć, co robią inni ludzie w takich sytuacjach. – Bee

Powiązane problemy