【问题标题】:Compiling x64 dll from x86 using Visual Studio 2008: unresolved external __imp_ symbols使用 Visual Studio 2008 从 x86 编译 x64 dll:未解析的外部 __imp_ 符号
【发布时间】:2011-03-19 10:15:25
【问题描述】:

我已经使用 Visual Studio 2008 将一些外部 C++ 代码编译成一个 dll,thirdpartycode.dll。该代码被包裹在 extern "C" 中。

由于我是交叉编译,所以在我的 32 位机器上创建一个 64 位 dll;我在“配置管理器”中使用 x64 作为“活动解决方案平台”。

我的thirdpartycode.dll 编译和链接成功。 接下来我要创建另一个包含调用thirdpartycode.dll 的代码的dll: 包装器.dll。 顾名思义,它是一个包装器,用于简化对thirdpartycode.dll 中复杂API 的某些调用。 然后我打算从 C# 程序中调用 wrapper.dll。

然而,我的问题是,当我尝试链接我的 wrapper.dll 时,我得到未解析的符号 :-(。 对于 thirdpartycode.dll 中的每个函数,例如“功能1”;我得到一个未解析的外部符号“__imp_func1”。使用 Dependency Walker 我验证了thirdpartycode.dll 确实导出了“func1”。

我确实在“附加依赖项”中列出了thirdpartycode.lib。我已打开 /VERBOSE 并且可以看到已搜索到 thirdpartycode.lib。

如果我重复整个过程,但使用 x86 作为“主动解决方案平台”,一切都会正常!?

有什么想法吗?

__imp_ 前缀从何而来? 这有点令人困惑,因为为了进行故障排除,我会将使用 Dependency Walker 从thirdpartycode.dll 导出的符号与使用dumpbin 从wrapper.obj 导出的符号进行比较。

提前感谢您的任何回答!

【问题讨论】:

  • 什么是未解析的符号名称?它们是系统函数还是来自第 3 方代码(即外部库)?
  • 它们来自第三方代码。
  • 对不起,我忘了提到第 3 方代码使用 Windows 系统库。当我在 Dependency Walker (depends.exe) 中打开它时,我注意到一些奇怪的事情:我的 dll 被标记为 64 位。但是,我的 dll 取决于 32 位的 C:\windows\system32\ntdll.dll 和 C:\windows\system32\kernel32.dll !结果,Dependency Walker 给了我以下错误:“错误:由于隐式依赖模块中缺少导出函数,至少一个模块具有未解析的导入。错误:找到了具有不同 CPU 类型的模块。”

标签: c++ c visual-studio visual-studio-2008


【解决方案1】:

只是为了验证,当您将thirdpartycode.lib 添加到“附加依赖项”时,您确保包含libs 位置的路径是否正确?在 Linker->General 的“其他库目录”部分下。

另外,如果项目在同一个解决方案中,您是否确保您的构建顺序是第三方代码项目在您的代码之前构建?

【讨论】:

  • 是的,是的。同样从使用 /VERBOSE 的链接器的输出中,我可以看到已经搜索了 thirdpartycode.lib。
  • 感谢您的建议 JMcCarty,但我认为肯定有其他问题。
【解决方案2】:

我在通过存根库链接到 64 位 dll 时遇到了类似问题。我的 32 位应用程序似乎链接到 32 位 dll,declspec(dllimport) 将 imp 附加到它查找的函数名称,但仅附加 _imp 64 位 dll。

例如,“function1()”将变为“_imp_function1”,并在我的 32 位版本的 dll 中找到,但当我链接 64 位版本的 dll 时进入我的 64 位应用程序,我收到错误:

未解析的外部符号 __imp_function ...

请注意附加到 __imp 的单下划线与 32 位版本的双下划线。当我无法以 32 位链接所需的库时,我收到链接错误:

未解析的外部符号_imp_function ...

我可以通过将 _ 附加到我的标头中的函数名称(即 _function() 而不是 function() 来解决问题。这是一个杂项,但它表明 64 位的装饰确实不同declspec(dllimport) 与 32 位 declspec(dllimport) 的比较。

我正在使用 Visual Studio 2010 并链接到使用 gcc 创建的 dll。我在某处读到 Visual Studio 创建的 64 位 dll 用单个下划线 _imp 装饰,所以问题可能是 gcc 前后始终使用双下划线,但 VS 需要 32 位 dll以不同于 64 位 dll 的方式进行装饰。

我还没有设法在 Microsoft 的 MSDN 上找到这种不同的描述。谁能确认 declspec(dllimport) 在 Visual Studio 中修饰函数名称的方式存在 64 位和 32 位的差异?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    相关资源
    最近更新 更多