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



我有两个现有的可执行文件A和T,在相同的解决方案中,在我触摸它们之前它们都运行得很好。在可执行文件中,A是定义类P的头文件,以及静态实例MyP的原型。在可执行文件T中,我想在项目A中调用MyP的成员函数,所以我在头文件中的类和MyP的声明中(不是在定义中)添加了dllimport/export宏,并将头文件包含在项目T中。dlimport/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提出了unresolved external symbol "__declspec(import) <snip> referenced in function <snip>用于函数调用,unresolved external symbol "__declspec(dllimport) class P MyP" <snip>用于静态对象。我还在输出日志中看到,就在它开始链接:Creating library Debug/A.lib and object Debug/A.exp之后,这似乎是不祥的,因为它应该链接到现有的可执行文件。

我的问题是:我怎么能告诉MSVC 2010这些在哪里?我以为只要把A设为依赖项它就会自动算出来。我可以链接到现有的可执行文件,对吧?

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

您的A项目有一个头文件,并且可能有一个.cpp文件,其中包含该头文件中描述的项目的实现。假设您的头文件是foo.h,相关的实现是foo.cpp。编译时,在<solutiondir>ADebug<solutiondir>Arelease中间文件夹中应该有一个foo.obj中间文件。该文件可以被链接器使用。

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

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

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

使用A.LIB文件作为链接器的输入与在静态链接情况下使用foo.obj文件基本相同,只是lib文件最终位于解决方案输出目录<solutiondir>Debug中,而不是项目中间目录<solutiondir>ADebug中。

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

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

相关内容

  • 没有找到相关文章

最新更新