MSVC 无法解析链接可执行文件的外部符号

发布于 2024-11-28 22:58:39 字数 988 浏览 2 评论 0原文

我有两个现有的可执行文件 A 和 T,在同一个解决方案中,在我接触它们之前它们都运行得很好。在可执行文件 A 中,有一个定义类 P 的标头和静态实例 MyP 的原型。定义在项目 A 中编译。在可执行文件 T 中,我想调用项目 A 中 MyP 的成员函数,因此我将 dllimport/export 宏添加到标头中的类和 MyP 的声明中(而不是在定义处),并且包含项目 T 中的标头。dllimport/export 宏是标准的,并且 A_EXPORTS 在项目 A 中定义,但不在 T 中。

#ifdef A_EXPORTS
#define A_API __declspec(dllexport)
#else
#define A_API __declspec(dllimport)
#endif

//various definitions and includes, defining ENUM_RECORDING_TYPE and ERROR
A_API HFILE viosopen(const _TCHAR *path, ENUM_RECORDING_TYPE rt, int flags);
A_API struct P { 
    ERROR B(SHORT phraseNum);
};
A_API extern P MyP;

我在解决方案中添加了项目 A 作为项目 T 的依赖项。 A 仍然可以正常编译,但 T 为函数调用提供了未解析的外部符号“__declspec(import)在函数中引用”,以及未解析的外部符号“__declspec (dllimport) class P MyP" 用于静态对象。我还在输出日志中看到,就在它开始链接之后: 创建库 Debug/A.lib 和对象 Debug/A.exp 这似乎是不祥的,因为它应该链接到现有的可执行文件

我的问题是:我如何告诉 MSVC 2010 我在哪里?我认为简单地将 A 设置为依赖项就会自动发现我可以链接到现有的可执行文件,对吧?

I have two existing executables A and T, in the same solution that both ran just fine before I touched them. In executable A is a header defining a class P, and a prototype for a static instance MyP. The definitions are compiled in project A. In executable T, I wanted to call member functions of MyP in project A, so I added dllimport/export macros to the declarations of the class and MyP in the headers (not at the definitions), and included the headers in project T. The dllimport/export macros are standard, and A_EXPORTS is defined in project A, but not in T.

#ifdef A_EXPORTS
#define A_API __declspec(dllexport)
#else
#define A_API __declspec(dllimport)
#endif

//various definitions and includes, defining ENUM_RECORDING_TYPE and ERROR
A_API HFILE viosopen(const _TCHAR *path, ENUM_RECORDING_TYPE rt, int flags);
A_API struct P { 
    ERROR B(SHORT phraseNum);
};
A_API extern P MyP;

I added project A as a dependency on project T in the solution. A still compiles fine, but T comes up with unresolved external symbol "__declspec(import) <snip> referenced in function <snip> for the function calls, and unresolved external symbol "__declspec(dllimport) class P MyP" <snip> for the static object. I also see in the output log, right after it starts linking: Creating library Debug/A.lib and object Debug/A.exp which seems ominous since it's supposed to be linking against the existing executable.

My question is: how can I tell MSVC 2010 where those are? I thought simply setting A as a dependency would have it figure that out automatically. I can link against the existing executable, right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倒数 2024-12-05 22:58:39

静态链接您的程序,您不需要 __declspec() 内容,也不需要单独的项目来创建 LIB 文件。我认为您可以使用 A 项目中的 .obj 文件进行链接。

您的 A 项目有一个头文件,并且可能有一个 .cpp 文件,其中包含该头文件中描述的项目的实现。假设您的头文件是 foo.h,关联的实现是 foo.cpp。编译后,\A\Debug\A\release 中应该有一个 foo.obj 中间文件代码>中间文件夹。该文件可供链接器使用。

在项目 T 的属性中,找到 Linker |输入并更改“附加依赖项”属性以包含 foo.obj 文件。一种方法是使用相对文件路径来定位文件 - 例如调试配置中的 ..\A\Debug\foo.obj 。另一种方法是在“附加依赖项”中使用简单的文件名 - foo.obj - 然后使用 Linker |一般|其他库目录”来帮助链接器找到文件 - 例如,..\A\$(IntDir)。使用 $(IntDir) 宏的优点是相同的值适用于“调试”和“发布”设置。

请记住设置从 T 项目到 A 项目的构建依赖关系,以确保首先编译 A 项目,否则 foo.obj 文件可能不存在。当 T 链接器来寻找它时。在解决方案属性中,选择项目依赖项,然后设置项目 T 依赖于项目 A。

动态链接,您需要使用 A.LIB 文件,如 @ajay 所说。 __declspec(DllImport) 告诉编译器您正在导入哪些函数和数据,但不告诉它您从哪里导入这些内容,

使用 A.LIB 文件作为输入 。对于链接器来说就是与在静态链接情况下使用 foo.obj 文件相同,只是 lib 文件最终位于解决方案输出目录 \Debug 而不是项目中间文件中目录 \A\Debug

演练介绍了如何创建和使用DLL 可能是有用的背景。

To statically link your program you don't need the __declspec() stuff and you don't need a separate project to create a LIB file. I think you can just link using the .obj file from your A project.

Your A project has a header file and presumably has a .cpp file that contains the implementation of the items described in that header. Let's say your header file is foo.h and the associated implementation is foo.cpp. When compiled, there should be a foo.obj intermediate file in the <solutiondir>\A\Debug or <solutiondir>\A\release intermediate folder. That file can be used by the linker.

In project T's properties, find Linker | Input and change the "Additional Dependencies" property to include the foo.obj file. One approach would be to use a relative file path to locate the file - for example ..\A\Debug\foo.obj in your debug configuration. Another approach is to use the simple file name in "Additional Dependencies" - foo.obj - and then use Linker | General | Additional Library Directories" to help the linker find the file - e.g., ..\A\$(IntDir). Using the $(IntDir) macro has the advantage that the same value works for Debug and Release settings.

Remember to set up a build dependency from your T project to your A project to be sure the A project is compiled first. Otherwise the foo.obj file might not exist when the T linker comes to look for it. In the Solution properties, select Project Dependencies and then set Project T depends on Project A.

To dynamically link you need to use the A.LIB file as @ajay said. The __declspec(DllImport) tells the compiler what functions and data you are importing but doesn't tell it where you are importing those things from.

Using the A.LIB file as input to the linker is much the same as using the foo.obj file in the statically linking case except that the lib file ends up in the solution output directory <solutiondir>\Debug instead of the project intermediate directory <solutiondir>\A\Debug.

This walkthrough on creating and using a DLL might be useful background.

少女七分熟 2024-12-05 22:58:39

我假设项目 A 是 DLL 而不是 EXE,它已成功生成 LIB 文件。
您需要使用A.LIB作为项目B中的链接器输入。仅生成LIB文件不会使其他项目自动链接到它。

I asssume project A is DLL not an EXE, which is successfully producing a LIB file.
You need to use the A.LIB as Linker Input in project B. Just producing LIB file wont make other projects automatically link to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文