2009-08-18 3 views
20

Можно создать дубликат:
Why do we need extern “C”{ #include <foo.h> } in C++?Когда использовать extern "C" в C++?

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

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

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

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

+3

Дубликат http://stackoverflow.com/questions/67894/why-do-we-need-extern-c-include-foo-h-in-c – Aamir

+0

related: http://stackoverflow.com/questions/1041866/extern-c http://stackoverflow.com/questions/717729/does-extern-c-have-any-effect-in-c http://stackoverflow.com/questions/496448/how-to-correctly -use-The-ехЬегп-keword-в-с / –

ответ

29

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") 
    
10

Одно место, где ехЬегп «C» имеет смысл, когда вы связываете с библиотекой, которая была скомпилирована как код C.

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

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

Другое место, где используется 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.

 Смежные вопросы

  • Нет связанных вопросов^_^