由于未解析的符号,使用向导创建的 ATL 项目无法编译
Posted
技术标签:
【中文标题】由于未解析的符号,使用向导创建的 ATL 项目无法编译【英文标题】:ATL project created using wizard does not compile due to unresolved symbols 【发布时间】:2011-03-21 18:40:38 【问题描述】:我一直致力于在 Visual Studio 2008 中编译一个基本的 ATL 项目,但我一直遇到错误。最终我遇到了以下构建错误:
1>Linking...
1> Creating library Debug\SomeProject.lib and object Debug\SomeProject.exp
1>dllmain.obj : error LNK2001: unresolved external symbol _LIBID_SomeProjectLib
1>SomeObject.obj : error LNK2001: unresolved external symbol _LIBID_SomeProjectLib
1>SomeObject.obj : error LNK2001: unresolved external symbol _IID_ISomeObject
1>Debug\SomeProject.dll : fatal error LNK1120: 2 unresolved externals
我忽略了什么或做错了什么?以下是重现的步骤。
-
创建一个名为
SomeProject
的新ATL Project
。接受所有默认值。
在解决方案资源管理器中右键单击项目并选择Add > Class
。
选择ATL Simple Object
并输入SomeObject
作为其短名称。接受所有其他默认值。
此时项目构建良好。但是,我想将 IDL 拆分为多个文件以便更好地组织(我的 IDL 将有数千行长)。
-
右键单击项目并选择
Add > New Item
。
选择Midl File
并输入ISomeObject
作为其文件名。
打开SomeProject.idl
并剪切ISomeObject
接口声明。将其替换为 import "ISomeObject.idl";
。
将接口声明粘贴到ISomeObject.idl
。
为了满足微软的 IDL 编译器我们需要更改一些选项:
-
右键单击项目并打开其属性。转到
MIDL > Output
部分并输入以下值:
头文件:$(InputName).h
IID 文件:$(InputName)_i.cpp
代理文件:$(InputName)_p.cpp
生成类型库:No
转到C/C++ > Precompiled Headers
部分并将Create/Use Precompiled Header
设置为Not using Precompiled Header
。如果使用预编译的头文件,以后会有错误。
选择SomeProject.idl
文件以显示其属性。转到MIDL > Output
部分并将Generate Type Library
设置为Yes
。
从Generated Files
过滤器中删除SomeProject_i.h
和SomeProject_i.c
。
将以下现有项目添加到Generated Files
过滤器。您可能需要先尝试编译项目。
SomeProject.h
SomeProject_i.cpp
ISomeObject.h
ISomeObject_i.cpp
现在,此时我希望项目能够编译。但事实并非如此。您应该会收到我在此问题顶部列出的 LNK1120
错误。
有什么想法吗?我忽略了一些简单的事情吗?
【问题讨论】:
【参考方案1】:不确定你在做什么,或者你为什么这样做,但是在某个地方你丢失了 midl.exe 生成的 blah_i.c 源代码文件。它包含接口、coclasses 和类型库的 GUID,链接器抱怨的那些。如果找不到,请在 *.c 文件中搜索 MIDL_DEFINE_GUID。
编辑:我现在看到了问题,您将 blah_i.c 重命名为 blah_i.cpp。错了,该文件包含 C 声明。当编译为 C++ 代码时,编译器会以不同的方式处理标识符。将其重命名为 .c。或者使用 /Tc 编译选项。
【讨论】:
我只是想建立一个简单的 ATL 项目。我正在做的唯一真正的改变是将接口定义移动到它自己的 IDL 文件中。 IID 文件正在生成并包含在内。请参阅我在设置项目时采取的最后一步。 OMFG...名字篡改...多么阴险。由于生成文件中的所有#ifdef __cplusplus,我的印象是支持在C++下编译。【参考方案2】:打开 VS 2008 命令提示符并转到中间/输出目录并查看 someproject_i.obj。试试这样的:
dumpbin someproject_i.obj /symbols | find "LIBID"
如果目标文件中没有定义 libid,那就是问题所在。也许它有错误的名字?如果有一个名称正确,那么问题是链接器没有使用它。
【讨论】:
以上是关于由于未解析的符号,使用向导创建的 ATL 项目无法编译的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio:无法将ATL类添加到ATL项目中?