由于未解析的符号,使用向导创建的 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.hSomeProject_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 项目无法编译的主要内容,如果未能解决你的问题,请参考以下文章

创建带有连接点的简单 atl 对象 未生成火方法

无法让简单的 COM 项目工作:在哪里以及如何实施?

ATL“实现界面向导”

Visual Studio:无法将ATL类添加到ATL项目中?

当项目名称带有连字符时,为啥 VS 2010 ATL 简单对象向导不会生成 .cpp/.h 文件?

未定义符号:ATL_chemv