2013-03-16 6 views

Odpowiedz

4

Musisz „wrap” dysku C interfejs ++ ze zwykłych funkcji C, które mają parametr pozwala określić, jakie obiekt oni zostanie wezwany. Na przykład, jeśli masz w C++

class A 
{ 
    // .. boilerplate stuff... 
    int SomeMethod(int n, float f); 
}; 

Następnie wraz z nim, można zadeklarować funkcji takich jak

extern "C" int A_SomeMethod(void* Obj, int n, float f) 
{ 
    return(((A*)Obj)->SomeMethod(n, f)); 
} 

Jeśli nie jesteś dobrze z odlewania void *, można zaimplementuj mapę z nieprzezroczystego uchwytu do A*. Ale najważniejsze jest, abyś trzymał się jakiegoś uchwytu/wskazówki do obiektu, do którego zostanie wywołana metoda. Aby uzyskać wskaźnik/uchwyt trzeba owinąć przydział do:

extern "C" void* A_Instantiate() 
{ 
    return new A; 
} 

katalogu C++ pliki powinny być opracowywane oddzielnie wzdłuż z pliku z funkcjami powyżej. Oddzielny dodatek do kompilacji C powinien zawierać deklaracje wszystkich powyższych funkcji.

EDYCJA: Ostrzeżenia i komentarze poniżej są ważne; aby odpowiedzieć na pytanie: "Tak, możliwe jest wywoływanie C++ z C", a to jest jedno podejście. To nie jest kompletne podejście, ponieważ nie ma na to mechanicznego sposobu, ale jest to początek. Nie należy również zapominać, aby utworzyć kolejną rozmowę-through dla delete, itp, itd.

+0

Dziękuję wilsonmichaelpatrick, ale co z użyciem * skompilowanego kodu * C++ w moim programie C ?! – S0H31L

+0

Co to jest 'A', które było używane podczas rzucania' Obj' ?! Czy jest to predefiniowany typ lub struktura ?! – S0H31L

+0

'A' jest typem klasy C++. Nawet przy skompilowanym kodzie C++ to podejście powinno działać. Wszystko, co musisz zrobić, to zdefiniować zewnętrzne metody "C" wzdłuż linii opisanych powyżej i użyć ich do połączenia się z twoim kodem C++. Sam kod C++ nie wymaga zmiany. – wilsonmichaelpatrick

0

tak, należy określić go jako

extern „C”

ten sposób sprawi, że funkcja mieć „C” podnośnik, a następnie kod C może wywołać swoją funkcję tylko tak jakby był w C. Ta nazwa funkcji nie zostanie zmanipulowana, ponieważ C nie obsługuje przeciążania.

tutaj pozwolę sobie zacytować @Faisal Vali:

  • extern "C" jest podnośnik-specyfikacja
  • Każdy kompilator jest wymagane aby zapewnić "C" podnośnik
  • specyfikacja połączenie nastąpi tylko w zakresie przestrzeni nazw
  • wszystkie typy funkcji, nazwy funkcji i nazwy zmiennych mają powiązanie językowe
  • dwa typy funkcji z odrębnym językiem wiązania GM są różne typy nawet jeżeli poza tym identyczny
  • podnośnik specyfikacje gniazdo wewnętrzna wyznacza się końcowe wiązanie
  • zewnętrzny „C” jest ignorowane przez członków klasy
  • najwyżej jednej funkcji określonej nazwy mogą mieć „C” powiązanie (niezależnie od przestrzeni nazw)
  • zewnętrzne "C" wymusza funkcję zewnętrznego powiązania (nie może uczynić jej statyczną)
  • Powiązanie C++ z obiektami zdefiniowanymi w innych językach oraz z obiektami zdefiniowanymi w C++ z innych języków jest implementacją zdefiniowane i zależne od języka. Tylko tam, gdzie strategie układ przedmiotem dwóch implementacje języków są na tyle podobne, takie połączenie może być osiągnięty

see Faisal Vali answer here

+0

To będzie działać tylko dla funkcji kompatybilnych z C (_one_ wersja przeciążonych funkcji, jeśli przeciążenie w tym jest w ogóle obsługiwane, brak odwołań, na pewno nie funkcje składowe, ani dla klas ani obiektów, mogą używać obiektów i klas wewnętrznie _nie_ i z wieloma ograniczeniami). Nie jest to intencją normy, to być w stanie wywołać C z C++, a nie na odwrót; może to być zabronione przez twój toolchain C++/C. – vonbrand

0

Q: Czy mogę uzyskać dostęp do mojego kodu C z C++ lub odwrotnie?

O: Tak.

1) Najważniejsze jest, aby używać extern "C" { ...} we wszystkich nagłówkach do określenia funkcji i danych C-tylko coś takiego:

http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B

/* Header file foo.h */ 
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */ 
extern "C" { 
#endif 

/* These functions get C linkage */ 
void foo(); 

struct bar { /* ... */ }; 

#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */ 
} 
#endif 

2) Zwykle scenariusz jest C++ głównym program wywołujący mieszankę funkcji i struktur C i C++. Struktury i funkcje są zadeklarowane w nagłówkach, a wszystkie mają "#ifdef __cplusplus/extern C".

3) Tutaj jest dobrym FAQ mieszania C i C++:

http://www.parashift.com/c++-faq/mixing-c-and-cpp.html

+2

Z tego, co przeczytałem: jest to projekt w C, który próbuje wywołać jakiś kod C++, i odpowiadasz tak, jakby był to program C++ wywołujący funkcje C. – qdii

+0

@ paulsm4: tnx za odpowiedź, ale qdii ma rację :) – S0H31L

0

ile bezwzględnie wymagane, to tylko dla dyied-in-the-wełny masochistów. Wykonanie tej czynności będzie wymagało wyjątkowej staranności po obu stronach i może dobrze działać dzisiaj, a następnie może być efektem spektakularnej eksplozji dzięki kolejnej aktualizacji kompilatora. C++ wymaga dużej ilości pomocy podczas pracy, a sprawne działanie z C nie jest zwykle obsługiwane. Możesz wywołać C z C++, który jest oficjalnie obsługiwany (i część standardu, extern "C" i inne).

Prawdopodobnie najlepiej jest napisać C w podzbiorze obsługiwanym przez C i C++ (punkt początkowy na subtelnych różnicach to this) i skompilować z kompilatorem C++. Albo przebolej to i zdecyduj, jaki język lubisz najbardziej.

+0

dzięki, a co z wykorzystaniem skompilowanego kodu C++ w moim programie C ?! P.S: Jest * Ściśle wymagane! *: S – S0H31L

+0

Kompilacja z kompilatorem C++. Wszystko inne to szaleństwo. Powodem, dla którego nie należy używać C++, jest albo kwestia związana z językiem (programista nie zna języka, z powodu polityki, jest uważany za zbyt nieefektywny, cokolwiek) lub ze względu na wymagania środowiska wykonawczego. Te pierwsze można rozwiązać i używać C++ w sposób jednolity; drugie koszty, które zapłacisz chimerą, poza dodatkowymi problemami związanymi z mieszaniną językową. – vonbrand

Powiązane problemy