Mam bibliotekę C ++, która udostępnia różne klasy do zarządzania danymi. Mam kod źródłowy biblioteki.
Chcę rozszerzyć interfejs API C ++, aby obsługiwał wywołania funkcji C, aby biblioteka mogła być używana z kodem C i kodem C ++ w tym samym czasie.
Używam łańcucha narzędzi GNU (gcc, glibc itp.), Więc obsługa języka i architektury nie stanowi problemu.
Czy są jakieś powody, dla których tak jest technicznie niemożliwe?
Czy są jakieś pułapka, na którą muszę uważać?
Czy są dostępne zasoby, przykładowy kod i / lub dokumentacja na ten temat?
Kilka innych rzeczy, o których się dowiedziałem:
- Użyj poniższego, aby zawinąć nagłówki C ++, które muszą być używane przez kod C.
#ifdef __cplusplus
extern "C" {
#endif
//
// Code goes here ...
//
#ifdef __cplusplus
} // extern "C"
#endif
- Przechowuj "prawdziwe" interfejsy C ++ w oddzielnych plikach nagłówkowych, które nie są objęte zasadą C. Pomyśl o PIMPL tutaj o . Używanie
#ifndef __cplusplus #error
rzeczy pomaga tutaj wykryć jakiekolwiek szaleństwo. - Uważaj na identyfikatory C ++ jako nazwy w kodzie C.
- Wyliczenia różniące się rozmiarem między kompilatorami C i C ++. Prawdopodobnie nie stanowi to problemu, jeśli używasz łańcucha narzędzi GNU, ale mimo to bądź ostrożny.
W przypadku struktur postępuj zgodnie z następującym formularzem, aby C nie pomylił się.
typedef struct X { ... } X
Następnie użyj wskaźników do przekazywania obiektów C ++, po prostu muszą być zadeklarowane w C jako struktura X, gdzie X jest obiektem C ++.
Wszystko to dzięki uprzejmości przyjaciela, który jest czarodziejem w C ++.
Odpowiedzi:
Tak, z pewnością jest to możliwe. Będziesz musiał napisać warstwę interfejsu w C ++, która deklaruje funkcje z
extern "C"
:Następnie zadzwonisz
foo()
z modułu C, który przekaże wywołanie dorealFoo()
funkcji zaimplementowanej w C ++.Jeśli chcesz udostępnić pełną klasę C ++ ze składowymi danych i metodami, być może będziesz musiał wykonać więcej pracy niż ten prosty przykład funkcji.
źródło
extern "C"
należy umieszczać je tylko w deklaracjach (a nie w definicjach)? Ponieważ wspomniałeś o „warstwie, która deklaruje funkcje”, ale Twój przykładowy kod jest również definicją. Innymi słowy, czy powinniśmy umieścić go w plikach nagłówkowych czy źródłowych? (Lub obu?)extern "C"
. Twój kompilator powie ci, czy musisz również umieścić to w definicji.C ++ FAQ Lite: „Jak mieszać kod C i C ++” .
Niektóre problemy opisano w odpowiedziach na następujące pytania:
źródło
Główny problem: wyjątków nie można przechwytywać w C. Jeśli istnieje możliwość wystąpienia wyjątku w kodzie C ++, należy bardzo uważnie napisać swój kod C lub opakowania C ++. I odwrotnie, mechanizmy typu wyjątków (tj. Longjump) w kodzie C (występujące w różnych językach skryptowych) nie są wymagane do wywoływania destruktorów obiektów C ++ na stosie.
źródło
możesz mieszać kod C / C ++. Jeśli twoja funkcja main () jest w C ++, wystarczy upewnić się, że funkcje c są zadeklarowane
Jeśli Twoim głównym jest C, prawdopodobnie wszystko jest w porządku, z wyjątkiem zmiennych statycznych. Wszelkie konstruktory ze zmiennymi statycznymi powinny być wywoływane przed uruchomieniem funkcji main (). To się nie stanie, jeśli C jest Twoim głównym. Jeśli masz dużo zmiennych statycznych, najlepiej jest zamienić zmienne statyczne na pojedyncze.
źródło