Использование extern для включения файлов в C или C++

Как это работает в C или C++?

extern "C" {
#include <unistd.h>
#include <fd_config.h>
#include <ut_trace.h>
#include <sys/stat.h>
#include <sys/types.h>
}

4 ответа

Стандарт C++ не определяет, как компиляторы должны называть символы в своих объектных файлах (например, Foo::bar() может закончиться как __clsFoo_fncBar или какой-нибудь болтун). Стандарт C делает, и он почти всегда отличается от того, как это делают компиляторы C++ (C не должен иметь дело с классами, пространствами имен, перегрузкой и т. Д.).

В результате, когда вы ссылаетесь на объектный файл, который был выведен компилятором C, вы должны указать своему компилятору C++ искать символы с именами, которые соответствуют стандарту C. По сути, вы помещаете его в "режим C". Это то, что "C" часть extern "C" делает.

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

Если в вашем Project есть исходные файлы на C и C++, и вам нужно собрать целиком (файлы C вызывают некоторые функции в файлах C++), поэтому нам нужно защитить вызовы функций и символы файла C, объявив, как в файлах C++,

extern "C" { /символы, используемые в файлах c/ uint8 GetCurrentthreadState (HANDLE ThreadId)

}

Затем компилятор C++ генерирует выходные данные компиляции, которые совпадают с данными компилятора C для вышеуказанных объявленных функций и символов. Так что во время компоновки компилятор может легко связать определенные символы C и C++ без любой ошибки компоновки.

Поэтому мое мнение не нужно для проверки #ifdef __cplusplus при компиляции. Потому что нам нужно защищать символы в файлах C++, верно? Также C++ файлы могут быть скомпилированы компилятором C++ только верно?

/ Renjith G

Это не будет работать, вам нужно добавить препроцессор cplusplus...

#ifdef __cplusplus
extern "C" {
#endif

// your code


#ifdef __cplusplus
}
#endif

РЕДАКТИРОВАТЬ:

В C++ имя будет обрабатываться так же, как в C, что означает, что имя mangle не будет. Это позволяет сделать различие между двумя разными функциями C++ с разными типом / номером аргумента или разным пространством имен в библиотеке (для библиотечной цели libname.so, libname.a). Если имя искажено, программа на С не сможет его распознать

eg:
int myfction()
void myfunction(int)
void myfunction(int, char)

C library:   myfction

C++ library: int_myction (it depend on your compiler)
C++ library: int_myction_int (it depend on your compiler)
C++ library: int_myction_int_char (it depend on your compiler)
// ... which is not allowed in C program

Каждый компилятор C++ должен поддерживать внешнюю связь "C". Код в таком блоке может быть устаревшим кодом, написанным на C для определенной функциональности, которая требуется для текущей программы.

Как это реализовано, в основном зависит от компилятора, однако я слышал, что многие компиляторы отключают искажение имени и изменяют соглашение о вызовах.

Другие вопросы по тегам