Когда использовать extern " C " в C++? [дубликат]

Возможные Дубликаты:
зачем нам нужен extern" C " { #include } на C++?

Я часто видел программы, закодированные как:

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

Почему мы используем extern "C" блок? Можем ли мы заменить это чем-то на C++? Есть ли преимущество использования extern "C"?

Я вижу ссылку, объясняющую этой но зачем нам нужно что-то компилировать на C, когда у нас уже есть c++?

2 ответов


extern " C " делает имена не искаженными.

используется для:

  1. нам нужно использовать некоторую библиотеку C в C++

    extern "C" int foo(int);
    
  2. нам нужно экспортировать некоторый код C++ в C

    extern "C" int foo(int) { something; }
    
  3. нам нужна возможность разрешить символ в общей библиотеке - поэтому нам нужно избавиться от искажения

    extern "C" int foo(int) { something; }
    ///
    typedef int (*foo_type)(int);
    foo_type f = (foo_type)dlsym(handle,"foo")
    

одно место, где extern " C " имеет смысл, когда вы связываетесь с библиотекой, которая была скомпилирована как код C.

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

В противном случае вы можете получить ошибки компоновщика, потому что библиотека содержит функции с C-linkage (_myfunc), но компилятор C++, который обработал заголовок библиотеки как код c++, сгенерировал имена символов C++ для функций ("_myfunc@XAZZYE" - это называется искажением и отличается для каждого компилятора).

другое место, где используется extern" C это гарантирует связь C даже для функций, написанных на C++, например.

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

такая функция может быть экспортирована в DLL и затем будет вызываться с другого языка программирования, потому что компиляция не будет искажать ее имя. Если вы добавили еще одну перегрузку той же функции, например.

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

большинство компиляторов поймают это и, таким образом, не позволят вам использовать перегрузки функций в ваших DLL-публичных функциях.