Чтобы использовать код C ++ в файле C, я прочитал, что мы можем просто сделать extern "C" { (where the c++ code goes here)}
, но когда я пытаюсь распечатать что-то с помощью cout, я получаю сообщение об ошибке, потому что он не распознает библиотеку. Я думаю, что я просто запутался в том, как extern «C» позволяет вам использовать код C ++ в C.
Противоположность верна. Вы можете использовать extern C, чтобы добавить код, который вы хотите скомпилировать, как код C, используя компилятор C ++.
Если я что-то упустил, вы не можете скомпилировать код C ++ с помощью компилятора C.
extern "C"
Конструкция — это специфический для C ++ синтаксис, никакой компилятор C его не поймет.
Вот почему вы почти всегда увидите это в сочетании с некоторыми условная компиляция лайк
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
Какие extern "C"
делает это просто запретить название искажения Это означает, что символы, определенные в исходном файле C ++, могут быть использованы в программе на Си.
Это позволяет вам иметь проект со смешанными источниками C и C ++, а источник C может вызывать функции C ++, которые были определены как extern "C"
,
Очень простой и глупый пример, чтобы показать смысл:
Допустим, у нас есть исходный файл C, скомпилированный с помощью компилятора C:
#include <stdio.h>
void foo(void); // Declare function prototype, so it can be called
int main(void)
{
printf("Calling foo...\n");
foo();
printf("Done\n");
return 0;
}
Тогда у нас есть исходный файл C ++ для foo
функция:
#include <iostream>
extern "C" void foo()
{
std::cout << "Hello from foo\n";
}
Исходный файл C компилируется компилятором C, а исходный файл C ++ компилируется компилятором C ++. Затем два объектных файла соединяются вместе, образуя исполняемую программу. Так как foo
был определен как extern "C"
его имя символа в объектном файле не искажено, и компоновщик может разрешить ссылку из объектного файла, созданного компилятором C.
Это работает и в другом направлении. Поскольку символы в C не искажены, компилятор C ++ должен это знать, и это делается путем объявления символов C extern "C"
обычно в заголовочном файле с использованием условной компиляции, как показано выше. Если extern "C"
не использовался, компилятор C ++ считал бы, что символы являются символами C ++, и искажал имена, приводя к проблемам с компоновщиком, когда компоновщик не мог найти искаженные символы.
Пример такой же глупости: сначала исходный файл C ++
#include <iostream>
extern "C" void bar(); // Declare function prototype as an unmangled symbol
int main()
{
std::cout << "Calling bar...\n";
bar();
}
Тогда исходный файл C
#include <stdio.h>
void bar(void)
{
printf("Inside bar\n");
}
extern "C"
способ поместить код C в код C ++. Более конкретно, он говорит компилятору отключить некоторые вещи, такие как перегрузка функций, чтобы он также мог отключить искажение имени. В C ++ простая функция, такая как:
int add(int a, int b) {
return a+b;
}
На самом деле получит какое-нибудь прикольное имя в библиотеке для обозначения параметров, так что если вы определите другую функцию, например:
double add(double a, double b) {
return a+b;
}
Что он знает, какой позвонить. Вы не хотите этого, если вы пытаетесь использовать библиотеку C и вот что extern "C"
для. Все это, как говорится, extern "C"
не допускает C ++ в программе на C
Экспортируемые символы C ++, как генерируется моим компилятором, являются искромсанный включить в компоновщик дополнительную информацию о типе символа.
Таким образом, следующие перегруженные функции будут различаться компоновщиком в C ++, но не в C:
int fn();
int fn(int);
int fn(char*);
int fn(char*) const;
int fn(const char*);
extern "C" {
… }
синтаксис позволяет определять символы (или ссылки на символы C) в коде C ++ без использования mangling
правила.
Это позволяет связать такой код C ++ с библиотеками C.