【问题标题】:ATL project created using wizard does not compile due to unresolved symbols由于未解析的符号,使用向导创建的 ATL 项目无法编译
【发布时间】: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

我忽略了什么或做错了什么?以下是重现的步骤。

  1. 创建一个名为SomeProject 的新ATL Project。接受所有默认值。
  2. 在解决方案资源管理器中右键单击项目并选择Add > Class
  3. 选择ATL Simple Object 并输入SomeObject 作为其短名称。接受所有其他默认值。

此时项目构建良好。但是,我想将 IDL 拆分为多个文件以便更好地组织(我的 IDL 将有数千行长)。

  1. 右键单击项目并选择Add > New Item
  2. 选择Midl File 并输入ISomeObject 作为其文件名。
  3. 打开SomeProject.idl 并剪切ISomeObject 接口声明。将其替换为 import "ISomeObject.idl";
  4. 将接口声明粘贴到ISomeObject.idl

为了满足微软的 IDL 编译器我们需要更改一些选项:

  1. 右键单击项目并打开其属性。转到MIDL > Output 部分并输入以下值:
    • 头文件:$(InputName).h
    • IID 文件:$(InputName)_i.cpp
    • 代理文件:$(InputName)_p.cpp
    • 生成类型库:No
  2. 转到C/C++ > Precompiled Headers 部分并将Create/Use Precompiled Header 设置为Not using Precompiled Header。如果使用预编译的头文件,以后会有错误。
  3. 选择SomeProject.idl 文件以显示其属性。转到MIDL > Output 部分并将Generate Type Library 设置为Yes
  4. Generated Files 过滤器中删除SomeProject_i.hSomeProject_i.c
  5. 将以下现有项目添加到Generated Files 过滤器。您可能需要先尝试编译项目。
    • SomeProject.h
    • SomeProject_i.cpp
    • ISomeObject.h
    • ISomeObject_i.cpp

现在,此时我希望项目能够编译。但事实并非如此。您应该会收到我在此问题顶部列出的 LNK1120 错误。

有什么想法吗?我忽略了一些简单的事情吗?

【问题讨论】:

    标签: visual-studio-2008 linker atl idl


    【解决方案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,那就是问题所在。也许它有错误的名字?如果有一个名称正确,那么问题是链接器没有使用它。

    【讨论】:

      猜你喜欢
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多