1

环境是 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));
}

我的文件.cpp

#include "SDKHeader.h"

int main() { return 0; }

将 MyFile.cpp 编译为可执行文件失败,链接器抱怨 CallIntoAnotherC_API 是未解析的外部。

4

1 回答 1

0

乔纳森·莱弗勒!非常感谢您为我指明了正确的方向。我发现了问题所在,至少可以说它非常奇怪。在我上面发布的 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));
}

删除这个无关的声明可以消除链接器错误,也可以防止虚假符号出现在目标文件中。

于 2016-05-29T20:07:54.907 回答