Внешние функции "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));
}

Удаление этого постороннего объявления избавляет от ошибок компоновщика, а также предотвращает отображение поддельного символа в объектном файле.

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