Когда "extern C" необходим в c ++ в Windows? - PullRequest
9 голосов
/ 16 сентября 2010

Поскольку мы знаем, что мы можем использовать функции c непосредственно в c ++ , когда тогда необходимо extern "C"?

Ответы [ 5 ]

13 голосов
/ 16 сентября 2010

Если ваша функция реализована в файле .c, файлам .cpp потребуется внешняя ссылка "C", иначе они будут ссылаться на искаженное имя функции в стиле C ++, и ссылка не будет выполнена.

Это также удобно для экспорта функций из библиотек DLL, так что они экспортируются с не искаженным именем.

9 голосов
/ 16 сентября 2010

Существует два довольно разных варианта использования extern "C". Один из них - определить функцию в C ++, которую вы должны вызывать из C. Т.е. вы пишете код на C ++, но он должен взаимодействовать с кодом C. В этом случае вы определяете функцию как extern "C":

extern "C" {
    int c_callable_func1() {}
    int c_callable_func2() {}
}

Когда вы делаете это, интерфейс этих функций должен следовать в значительной степени тем же правилам, что и в C (например, вы не можете перегружать функции или использовать значения по умолчанию для любых параметров).

Другая (значительно более распространенная) ситуация состоит в том, что у вас есть код, написанный на C, который вы хотите вызывать из C ++. В этом случае функции определения остаются такими же, как и раньше, но функции должны быть объявлены / прототипированы как extern "C". В типичном случае вы хотите использовать один заголовок, который может быть #include d в файле C или C ++, поэтому структура выглядит примерно так:

// myheader.h
#ifndef MY_HEADER_H_INCLUDED_
#define MY_HEADER_H_INCLUDED_

#ifdef __cplusplus
extern "C" {
#endif

    int func1(void);
    void func2(int);

#ifdef __cplusplus
}
#endif

#endif

Итак, компилятор C ++ увидит объявления функций (и typedef s и т. Д.), Окруженные блоком extern "C", в то время как компилятор C увидит прототипы, не окруженные чем-то, что он не распознает.

В первом случае (функции C ++, вызываемые из C), вы обычно будете структурировать заголовок примерно таким же образом, так что вы также можете вызывать эти функции из C ++, если это необходимо (но в интерфейсе вы по-прежнему теряете все дополнительные функции). C ++, как перегрузка функций).

9 голосов
/ 16 сентября 2010

Это необходимо, когда функция C++ должна вызываться кодом C, а не кодом C++.

По сути, когда вы хотите, чтобы ваша библиотека C++ была обратно совместимой.

4 голосов
/ 16 сентября 2010

Как вы знаете, c ++ поддерживает перегрузку функций, которые многократно определяют одну и ту же функцию или метод с разными параметрами.Для этого компилятор должен добавить некоторую часть символов для каждого из них ... например, компилятор изменит имя функции foo в следующем объявлении с

void foo(int f,char c);

на

foo@i&c

К сожалению, C не поддерживает это.Все имена функций остаются неизменными после компиляции.Итак, чтобы вызвать функцию c ++ из c, вы должны знать точное имя после модификации, и я думаю, что это сложно и отличается от компилятора к другому.c и остановите компилятор от изменения имен, которые вы должны использовать для этого ключевого слова, например

extern "C" { 
void foo(int f,char c);
}

и все !!!

3 голосов
/ 16 сентября 2010

Поскольку сигнатуры функций, генерируемые компиляторами C и C ++, отличаются - это устанавливает соглашение C для функции C даже при использовании C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...