Kiedy używać extern " C " w C++? [duplikat]

Możliwy duplikat:
Dlaczego potrzebujemy extern" C " {#include } W C++?

Często widziałem programy zakodowane jak:

extern "C" bool doSomeWork() {
  //
  return true;
}

Dlaczego używamy extern "C" bloku? Czy możemy to zastąpić czymś w C++? Czy jest jakaś korzyść z używania extern "C"?

Widzę link wyjaśniający to ale po co mamy kompilować coś w C skoro mamy już C++?

 22

2 answers

Extern "C" sprawia, że nazwy nie są zniekształcone.

Używany, gdy:

  1. Musimy użyć jakiejś biblioteki C w C++

    extern "C" int foo(int);
    
  2. Musimy wyeksportować jakiś kod C++ do C

    extern "C" int foo(int) { something; }
    
  3. Potrzebujemy umiejetnosci rozwiazania symbolu w bibliotece dzielonej -- wiec musimy sie pozbyc]}

    extern "C" int foo(int) { something; }
    ///
    typedef int (*foo_type)(int);
    foo_type f = (foo_type)dlsym(handle,"foo")
    
 31
Author: Artyom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-18 06:35:30

Jednym z miejsc, gdzie extern "C" ma sens, jest linkowanie do biblioteki, która została skompilowana jako kod C.

extern "C" {
  #include "c_only_header.h"
}

W przeciwnym razie mogą pojawić się błędy linkera, ponieważ biblioteka zawiera funkcje z C-linkage (_myfunc), ale kompilator C++, który przetwarzał nagłówek biblioteki jako kod C++, generował nazwy symboli C++ dla funkcji ("_myfunc@XAZZYE" - nazywa się to mangling i różni się dla każdego kompilatora).

Innym miejscem, gdzie używane jest extern " C " jest zagwarantowanie C linkage nawet dla funkcji napisanych w C++, np.

extern "C" void __stdcall PrintHello() {
  cout << "Hello World" << endl;
}

Taka funkcja może zostać wyeksportowana do biblioteki DLL, a następnie może być wywołana z innego języka programowania, ponieważ kompilacja nie zmieni jej nazwy. Jeśli dodałeś kolejne przeciążenie tej samej funkcji, np.

extern "C" void __stdcall PrintHello() {
  cout << "Hello World" << endl;
}
extern "C" void __stdcall PrintHello(const char *name) {
  cout << "Hello, " << name << endl;
}

Większość kompilatorów wychwyciłaby to i tym samym uniemożliwiłaby używanie funkcji przeciążonych w publicznych funkcjach DLL.

 13
Author: Cygon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-18 06:42:20