【发布时间】:2014-03-14 14:47:48
【问题描述】:
我的解决方案中有以下设置(所有 C++):
- Project1,编译为静态库 (.lib)。
- Project2 编译为 DLL,包含 1 中生成的 .lib。
- Project3,包含2中生成的DLL。
现在我想将 project1 的功能公开给 project3,而不直接包含项目 1 的 .lib。我一直遇到链接器错误。
error LNK2001: unresolved external symbol
项目 1 设置为通过以下方式使用 dllexport 和 dllimport(当然,FOO_API 在要公开的类/方法之前):
#if defined(FOO_STATIC)
#define FOO_API
#define FOO_TEMPLATE(type) template class type
#else
#ifdef FOO_EXPORTS
#define FOO_API __declspec(dllexport)
#define FOO_TEMPLATE(type) template class FOO_API type
#else
#define FOO_API __declspec(dllimport)
#define FOO_TEMPLATE(type) extern template class FOO_API type
#endif
#endif
由于我们将 Project1 编译为静态库,因此不会采用 dllexport 路径(我们定义 FOO_STATIC)。然而,通过 Project2 的 DLL,我想公开 Project1 的方法。我尝试在 Project2 中创建一个定义 FOO_EXPORTS 的 .cpp 文件,然后包含包含我要导出的方法的文件的标题。所以:
// somefile_that_will_be_built.cpp
#define FOO_EXPORTS
#include "a.h"
#include "b.h"
#include "c.h"
我希望这会触发 Project1 中的 dllexport 代码,以便将其包含在 Project2 的 DLL 中。我希望当 Project3 包含 Project1 标头时,它会进入 dllimport 路径,并且链接器会找到所需的方法。所以:
#include "a.h"
class WrapThis:
public:
SomeMethodInA();
Project3 编译,但在链接过程中未找到 SomeMethodA()。我的方法不可能吗?我是否需要改为在 Project2 中编写模块定义文件?我希望防止这种情况发生,因为我们有一些名称歧义,并且名称修改也无济于事(我知道可以关闭它,但出于其他原因我不想这样做)。
任何帮助将不胜感激,因为我在这部分开发方面的经验有限。
更新
剩余错误(以4个为例):
2>Stdafx.obj : error LNK2028: unresolved token (0A000683) "public: void __cdecl fooEx::Load(char const * const)" (? Load@fooEx@Namespace4@Namespace1@Namespace2@Namespace3@@$$FQEAAXQEBD@Z) referenced in function "public: void __clrcall Namespace1::Namespace2::Namespace3::Namespace4::FooEx::Load(class System::String ^)" (?Load@FooEx@Namespace4@Namespace1@Namespace2@Namespace3@@$$FQE$AAMXPE$AAVString@System@@@Z)
2>Stdafx.obj : error LNK2028: unresolved token (0A000684) "public: void __cdecl fooEx::LoadHeader(char const * const)" (?LoadHeader@fooEx@Namespace4@Namespace1@Namespace2@Namespace3@@$$FQEAAXQEBD@Z) referenced in function "public: void __clrcall Namespace1::Namespace2::Namespace3::Namespace4::FooEx::LoadHeader(class System::String ^)" (?LoadHeader@FooEx@Namespace4@Namespace1@Namespace2@Namespace3@@$$FQE$AAMXPE$AAVString@System@@@Z)
2>Stdafx.obj : error LNK2028: unresolved token (0A000686) "public: void __cdecl fooEx::Save(char const * const,double,double)" (?Save@fooEx@Namespace4@Namespace1@Namespace2@Namespace3@@$$FQEAAXQEBDNN@Z) referenced in function "public: void __clrcall Namespace1::Namespace2::Namespace3::Namespace4::FooEx::Save(class System::String ^,double,double)" (?Save@FooEx@Namespace4@Namespace1@Namespace2@Namespace3@@$$FQE$AAMXPE$AAVString@System@@NN@Z)
2>Stdafx.obj : error LNK2028: unresolved token (0A000687) "public: void __cdecl fooEx::Save(char const * const)" (?Save@fooEx@Namespace4@Namespace1@Namespace2@Namespace3@@$$FQEAAXQEBD@Z) referenced in function "public: void __clrcall Namespace1::Namespace2::Namespace3::Namespace4::FooEx::Save(class System::String ^)" (?Save@FooEx@Namespace4@Namespace1@Namespace2@Namespace3@@$$FQE$AAMXPE$AAVString@System@@@Z)
Project1 - classA(使用 FOO_EXPORT 编译)到静态库中。
class FOO_API fooEx : public foo
{
public:
fooEx();
virtual void Free();
void Load(const char filename[]);
void LoadHeader(const char filename[]);
virtual void LoadRawData();
void Save(const char filename[]);
}
可能很重要:
Project1 使用预编译的头文件。
Load & LoadHeader 在多个文件中以完全相同的方式定义(foo 类的其他扩展名)。
虚拟方法在基类以及该基类的其他实现中定义。
Project2 - 编译为 DLL。通过链接器输入包括 Project1.lib,其他依赖项。
Project3 - 编译为 DLL。具有无法链接的方法的示例类。
【问题讨论】:
标签: c++ linker linker-errors dllimport dllexport