Я написал функцию C++, которую мне нужно вызвать из программы на C. Чтобы сделать его вызываемым с C, я указал extern "C"
на функцию декларация. Затем я скомпилировал код C++, но компилятор (Dignus Systems/C++) создал функцию mangled name для этой функции. Так что, по-видимому, он не почитал extern "C"
.Является ли extern «C» обязательным только для объявления функции?
Чтобы решить эту проблему, я добавил extern "C"
в функцию определение. После этого компилятор сгенерировал имя функции, которое может быть вызвано C. C.
Технически extern "C"
необходимо указывать только в объявлении функции. Это правильно? (У этого примера есть C++ FAQ Lite.) Должны ли вы также указать его на определение функции?
Вот пример, чтобы продемонстрировать это:
/* ---------- */
/* "foo.h" */
/* ---------- */
#ifdef __cplusplus
extern "C" {
#endif
/* Function declaration */
void foo(int);
#ifdef __cplusplus
}
#endif
/* ---------- */
/* "foo.cpp" */
/* ---------- */
#include "foo.h"
/* Function definition */
extern "C" // <---- Is this needed?
void foo(int i) {
// do something...
}
Моя проблема может быть результатом неправильно кодирования что-то, или я, возможно, нашли ошибку компилятора. В любом случае я хотел бы обратиться к stackoverflow, чтобы убедиться, что я знаю, что технически является «правильным».
Вы уверены, что на самом деле вы получаете mangling foo, если вы оставите extern «C» в foo.c в примере кода, который вы показываете? Или это было нечто, что произошло в другом более сложном коде? Я довольно часто видел эту проблему как признак забывания включить foo.h в foo.c. –
@Brooks Moses: Это отличный момент. В моем фактическом коде, который немного сложнее, чем этот пример «foo», я включаю заголовок в исходный файл «cpp». Что заставило меня думать, что компилятор искал имя: «Если я не включаю« extern »C» в определение функции, тогда в списке компилятора отображается внешний символ «foo_FPFPCc_v». Когда включен «extern» C », в листинге отображается внешний символ« foo ». – bporter
@bporter - может быть интересно поэкспериментировать с тем, что делает компилятор с упрощенным примером. Если он показывает то же поведение, вы можете отправить заметку поставщику. Если он не показывает то же самое, тогда вы должны отслеживать, что происходит в вашей реальной сборке, потому что это указывает на то, что вводится неправильный заголовок (или что-то еще делает объявление функции недоступным). –