Внешние функции "C" в скомпилированном объектном коде
Средой является Microsoft Visual C++ 2015 и Windows 7.
Есть ли что-то особенное в inline extern "C"
функции определены в заголовке? Я использую SDK, в котором один из заголовков содержит такого зверя. В моем приложении у меня есть одиночный TU (модуль перевода), чья единственная работа в жизни - включить вышеупомянутый заголовок. Это все. Ничего другого в этом нет. Если я копаюсь в сгенерированном объектном файле, я вижу extern "C"
Эта функция вызывает у меня некоторые нежелательные побочные эффекты (я пока опущу их, поскольку это может отвлечь от основной проблемы).
Почему это случилось? В клиентском коде ничего нет (помните, что мой одинокий TU пуст, кроме main()
точка входа и этот заголовок), который вызывает это, чтобы это произошло.
ОБНОВЛЕНИЕ с небольшим фрагментом, который может лучше объяснить, с чем я сталкиваюсь:
Вот что на самом деле происходит:
FooObj.h
FooObj::FooObj() { }
FooObj::~FooObj() { CallIntoAnotherC_API(); }
SDKHeader.h
#include <FooObj.h>
extern "C" inline void SomeFunc(void* user_data)
{
A* obj = static_cast<A*>(user_data);
obj->CallAnotherFunc(FooObj(33));
}
MyFile.cpp
#include "SDKHeader.h"
int main() { return 0; }
Компиляция MyFile.cpp в исполняемый файл завершается неудачно с компоновщиком, жалующимся на то, что CallIntoAnotherC_API является неразрешенным внешним.
1 ответ
Джонатан Леффлер! Большое спасибо за указание мне в правильном направлении. Я выяснил, в чем проблема, и это супер странно, если не сказать больше. В фрагменте SDKHeader.h, который я разместил выше, есть постороннее объявление SomeFunc, например:
#include <FooObj.h>
// I don't know why this declaration exists but its presence is
// causing the compiler to include SomeFunc and everything it references
// in the object file causing eventual linker errors! Also notice that
// this declaration even misses the "inline" keyword.
extern "C" void SomeFunc(void* user_data);
extern "C" inline void SomeFunc(void* user_data)
{
A* obj = static_cast<A*>(user_data);
obj->CallAnotherFunc(FooObj(33));
}
Удаление этого постороннего объявления избавляет от ошибок компоновщика, а также предотвращает отображение поддельного символа в объектном файле.