MSVC未解决外部符号链接可执行文件 [英] MSVC unresolved external symbol linking executables

查看:289
本文介绍了MSVC未解决外部符号链接可执行文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

//各种定义并包括定义ENUM_RECORDING_TYPE和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函数调用的函数< snip> 中引用未解析的外部符号__declspec(import)< snip> c $ c>未解析的外部符号__declspec(dllimport)类P MyP< snip> 为静态对象,我也看到在输出日志后,开始链接:创建库Debug / A.lib和对象Debug / A.exp 这似乎是不祥的,因为它应该与现有的可执行文件链接。



我的问题是:我怎么能告诉MSVC 2010这些是什么?我认为简单地将A设置为依赖将会自动显示出来,我可以链接现有的可执行文件,对吗?

解决方案

静态链接您的程序,您不需要__declspec()的东西,您不需要单独的项目来创建一个LIB文件,我想你可以使用.obj文件从A项目中链接。



您的项目有一个头文件,大概有一个.cpp文件,其中包含该标题中描述的项目的实现。假设你的头文件是 foo.h ,相关的实现是 foo.cpp 。编译时,在< solutiondir> \A\Debug 中应该有一个 foo.obj 中间文件或< solutiondir> \A\release 中间文件夹。该文件可以由链接器使用。



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



请记住从您的T项目建立一个构建依赖关系您的A项目确保先前编译了一个项目,否则当T链接器找到它时, foo.obj 文件可能不存在,在解决方案属性中,选择项目依赖关系,然后根据项目A设置项目T.



动态链接,您需要使用 A .LIB 文件作为@ajay说, __ declspec(DllImport)告诉编译器你正在导入什么函数和数据,但不告诉它哪里你正在导入这些东西。



使用 A.LIB 文件作为链接器的输入是一样的在静态链接中使用 foo.obj 文件g案例,除了lib文件结束于解决方案输出目录< solutiondir> \Debug 而不是项目中间目录< solutiondir> \A\Debug



这个演练关于创建和使用DLL可能是有用的背景。


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?

解决方案

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.

这篇关于MSVC未解决外部符号链接可执行文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆