C++ 如何消除LNK4221警告?

C++ 如何消除LNK4221警告?,c++,linker,C++,Linker,我正在从事一个使用c++/windows窗体(visual studio 2010)的项目,我们有4个项目: 1个包含GUI windows窗体{托管代码}的项目,这是exe项目 其他3个项目{非托管代码}都是静态库 在这4个项目中,我们不使用预编译头stdafx.h,公共语言运行时支持是纯MSIL公共语言运行时支持(/clr:Pure) 每个项目都包含其他3个项目作为附加的包含目录,链接库依赖项设置为“是” 我们有: 警告LNK4221:此对象文件未定义任何以前未定义的公共符号,因此任何使

我正在从事一个使用c++/windows窗体(visual studio 2010)的项目,我们有4个项目:

  • 1个包含GUI windows窗体{托管代码}的项目,这是exe项目
  • 其他3个项目{非托管代码}都是静态库
  • 在这4个项目中,我们不使用预编译头stdafx.h,公共语言运行时支持是纯MSIL公共语言运行时支持(/clr:Pure)
  • 每个项目都包含其他3个项目作为附加的包含目录,链接库依赖项设置为“是”
我们有:

警告LNK4221:此对象文件未定义任何以前未定义的公共符号,因此任何使用此库的链接操作都不会使用它

此警告出现在相同对象文件(.NETFramework,Version=v4.0.AssemblyAttributes.obj)中的3个静态库项目中

我们想消除它,但是在一些搜索之后,大多数主题都说预编译头是一个原因,而我们不使用它


有关此警告存在的原因以及如何消除它的任何新想法?

免责声明:此解决方案确实很糟糕,不应将此代码添加到生产版本中!只有“隐藏”警告才有用

更好的解决方案是从编译中删除有问题的文件,因为它无论如何都是无用的

原职: 我发现这个警告的问题源于几个依赖项,我发现它是由一些翻译单元为空(即空源文件)引起的

这些文件实际上有一个内容,但它在visual studio中已被停用,因此我只是在开头添加了:

__declspec( dllexport ) void getRidOfLNK4221(){}
现在我的项目编译时没有任何警告:)


希望它有帮助,即使这是一个迟来的答案

您会收到此警告,因为您仅在cpp文件中使用模板类。
为了消除它,插入一个简单的函数,没有模板。

< P>我有一个C++静态库,里面有一个空模块,在非优化模式下链接给了我LNK4221警告。(在Visual Studio中) 我转到图书管理员->所有选项,并在其他选项中添加了“/忽略:4221”。
因此,警告消失了。

这只是我的一个特殊问题,但是如果您的.cpp没有定义任何新函数或构造函数的体为空,您将收到此警告。我为构造函数使用了初始化列表,因此主体为空。

请参见:

总之,文件不导出任何内容,因此链接器不进行链接,因为它认为这是一种浪费

在“Visual Studio 2008命令提示符”中,输入以下命令(注意:此处使用命令行指定.obj文件的顺序;Visual Studio 2008将按字母顺序向链接器提供.obj文件)

cl/c a.cpp b.cpp

link/lib/out:test.lib a.obj b.obj

将为a.obj抛出LNK4221,如下所示

a.obj : warning LNK4221: no public symbols found; archive member will be inaccessible
对于上述情况,
atlbase.h
(随Visual Studio提供)包含一些符号定义,这些定义将包含在
a.obj
b.obj
中。此外,在
b.obj
中定义了一个函数func1。链接器将以后进先出的方式处理OBJ文件,因此当它处理
a.OBJ
时,它无法在其中找到任何新的公共符号,因为
b.OBJ
提供了
a.OBJ
拥有的所有公共符号,将抛出LNK4221。如果命令行2替换为以下内容

link/lib/out:test.lib b.obj a.obj

现在警告消失了


为什么不使用预编译的头文件呢?与此警告链接的对象文件有哪些-请发布链接器错误。stdafx.cpp文件是否已编译并链接?@ManuelH的链接显示了谷歌的第一次点击,这很好地解释了这一点!@Alex:我没有使用预编译头,因为它出现了几个错误,关于哪些对象文件,这个警告出现在同一个对象文件中的3个静态库项目中(\.NETFramework,Version=v4.0.AssemblyAttributes.obj),项目中没有stdafx文件。这太糟糕了。为什么这么糟糕?代码基本上生成了一个什么都不做的函数,然后告诉编译器不要删除它,实际上是将它作为符号公开。首先,这很“糟糕”,因为你试图说服编译器不要告诉你它看到你做的愚蠢的事情,然后用随机垃圾函数污染你的符号表和库二进制文件,使问题更加复杂,根据定义,这些垃圾函数是无意义的。更好的解决方案是修复这个答案中的警告,根本不编译无用的文件。按平台将实现拆分为文件,编译速度会更快。我遵循了你的建议。这个警告已经不存在了。但是,每包含一个头文件,就会出现一个新的LNK4006(:这是我在VS2013静态库项目中的场景。我在一个.h文件中有一个完全模板化的类和一个相应的(空的).cpp文件。我只是从项目中排除了.cpp文件。警告消失了,我(我很惊讶,但不应该是这样)使用静态库构建可执行文件时没有链接错误。