MSVC未解决外部符号链接可执行文件 [英] MSVC unresolved external symbol linking executables
问题描述
#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屋!