Использование 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 для определенной функциональности, которая требуется для текущей программы.
Как это реализовано, в основном зависит от компилятора, однако я слышал, что многие компиляторы отключают искажение имени и изменяют соглашение о вызовах.