【问题标题】:Code links only when static library compiled in C++ mode in Visual studio 2019仅当在 Visual Studio 2019 中以 C++ 模式编译静态库时才链接代码
【发布时间】:2021-12-12 13:15:02
【问题描述】:

我创建了一个 linked list manager 的 WIN32 静态库,我一直在使用它进行 C/C++ 开发。

我在 Visual Studio 2019 上编译了这个库,强制它编译为 C 代码(VS2019 首选项中的/TC 选项)。但是,我确实使用了

#ifdef __cplusplus
extern "C" {
#endif

在标题中,以防我的静态库被 C++ 程序使用。这是header的链接。

但是,当我在 C++ 项目中使用这个静态库时,会出现链接器错误

1>quickDAQ.obj : error LNK2019: unresolved external symbol "unsigned long __cdecl cListLength(struct _cLinkedList *)" (?cListLength@@YAKPAU_cLinkedList@@@Z) referenced in function "void __cdecl quickDAQstart(void)" (?quickDAQstart@@YAXXZ)
1>quickDAQ.obj : error LNK2019: unresolved external symbol "int __cdecl cListEmpty(struct _cLinkedList *)" (?cListEmpty@@YAHPAU_cLinkedList@@@Z) referenced in function "void __cdecl setSampleClockTiming(enum _sampling_modes,double,char *,enum _trigger_modes,unsigned __int64,bool)" (?setSampleClockTiming@@YAXW4_sampling_modes@@NPADW4_trigger_modes@@_K_N@Z)
1>quickDAQ.obj : error LNK2019: unresolved external symbol "struct _cListElem * __cdecl cListFirstElem(struct _cLinkedList *)" (?cListFirstElem@@YAPAU_cListElem@@PAU_cLinkedList@@@Z) referenced in function "void __cdecl enumerateNIDevices(void)" (?enumerateNIDevices@@YAXXZ)
1>quickDAQ.obj : error LNK2019: unresolved external symbol "struct _cListElem * __cdecl cListNextElem(struct _cLinkedList *,struct _cListElem *)" (?cListNextElem@@YAPAU_cListElem@@PAU_cLinkedList@@PAU1@@Z) referenced in function "void __cdecl enumerateNIDevices(void)" (?enumerateNIDevices@@YAXXZ)
1>quickDAQ.obj : error LNK2019: unresolved external symbol "void * __cdecl cListFirstData(struct _cLinkedList *)" (?cListFirstData@@YAPAXPAU_cLinkedList@@@Z) referenced in function "void __cdecl syncSampling(void)" (?syncSampling@@YAXXZ)
1>quickDAQ.obj : error LNK2019: unresolved external symbol "int __cdecl cListInit(struct _cLinkedList *)" (?cListInit@@YAHPAU_cLinkedList@@@Z) referenced in function "void __cdecl enumerateNIDevices(void)" (?enumerateNIDevices@@YAXXZ)
1>quickDAQ.obj : error LNK2019: unresolved external symbol "int __cdecl cListAppend(struct _cLinkedList *,void *)" (?cListAppend@@YAHPAU_cLinkedList@@PAX@Z) referenced in function "void __cdecl enumerateNIDevices(void)" (?enumerateNIDevices@@YAXXZ)
1>quickDAQ.obj : error LNK2019: unresolved external symbol "int __cdecl cListPrepend(struct _cLinkedList *,void *)" (?cListPrepend@@YAHPAU_cLinkedList@@PAX@Z) referenced in function "void __cdecl pinMode(unsigned int,enum _IOmodes,unsigned int)" (?pinMode@@YAXIW4_IOmodes@@I@Z)
1>quickDAQ.obj : error LNK2019: unresolved external symbol "void __cdecl cListUnlinkElem(struct _cLinkedList *,struct _cListElem *)" (?cListUnlinkElem@@YAXPAU_cLinkedList@@PAU_cListElem@@@Z) referenced in function "void __cdecl enumerateNIDevices(void)" (?enumerateNIDevices@@YAXXZ)
1>C:\Users\tyros\codebase\testingLinkedList\Debug\testingLinkedList.exe : fatal error LNK1120: 9 unresolved externals
1>Done building project "testingLinkedList.vcxproj" -- FAILED.

显然,链接器无法链接到静态库。

但是,如果我使用设置为 C++ (/TP) 的 compile as 标志来编译静态库,我正在使用该库的项目编译时不会出现上述错误。

这是为什么?

【问题讨论】:

  • 我的猜测是你应该告诉 extern C 的来源,而不仅仅是标题? extern C 关键字告诉编译器不要破坏名称,这是针对标头完成的,但如果不是针对源代码,则您有未引用的符号。
  • extern "C" 应该有效。所以编译器可能是#include 另一个.h 文件。使用 Project > Properties > C/C++ > Advanced > “Show Includes”和 C/C++ > Preprocessor > “Preprocess to a File”进行诊断。
  • 感谢您的回复。虽然将 extern C 放在源文件中没有帮助,但您检查未引用符号和显示包含的指针使我意识到 PEBKAC 发生了。我没有将修改后的头文件包含到使用静态库的新项目中。 [SMH]

标签: c++ c visual-studio visual-c++ linker-errors


【解决方案1】:

问题是 PEBKAC。我忘记包含新的头文件(具有 C++ 的外部“C”定义)以及新版本的静态库。这导致使用该库的 C++ 项目破坏符号。

故事的寓意 - 在更新 C++ 项目使用的库时,始终更改头文件和静态库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 2011-06-15
    • 2019-06-07
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    相关资源
    最近更新 更多