LNK2001:尝试从另一个 DLL 调用对象的方法时,未解析的外部符号

LNK2001: unresolved external symbol, when trying to call method of object from another DLL

本文关键字:方法 符号 外部 对象 另一个 调用 DLL LNK2001      更新时间:2023-10-16

我有两个模块,每个模块都有自己的类和自己的对象。每个模块都编译为一个 DLL。我想进行"跨DLL"方法调用,具有指向另一个类对象的指针,但链接器不允许这样做(MSVC++ 2008)。

更具体地说:

  • 有 calledModule.cpp,它调用了 Class,以及这个类的对象(calledObject);类有 calledMethod,我想调用它;模块被编译为 DLL 并成为(令人惊讶!)调用 Lib.dll。
  • 有callingModule.cpp,它有callingClass;除此之外,类有属性,它是指向calledObject的指针;模块被编译为DLL callingLib.dll;calledObject上的指针在构造函数中设置。

我能够编译整个代码。当链接器启动时,麻烦就来了。我得到以下信息:moduleCalling.obj : 错误 LNK2001: 未解析的外部符号 "public: void __thiscall classCalled::methodCall ..."

我不使用任何 declspec 的东西,所以没有从 calledLib.dll 导出任何内容。

我调用的方法(methodCalled)存在于实现中,它的原型在标头中正确声明。classCall 是一个"基本"类,不继承自任何内容。此外,整个项目编译并正常工作,当我声明方法调用为虚拟...

很难理解,为什么我不能从另一个DLL以"正常"方式调用对象的方法?为什么将其声明为"虚拟"会有所帮助?有人知道吗?我有一些猜测,但专家的回答将有助于理解这些东西。

PS:我正在使用MSVC++ 2008。

谢谢!

更新:添加代码片段,以反映代码的外观。

// part of calledLib.dll
// moduleCalled.h
class classCalled {
  public:
    int methodCalled() { return 1 };
};
// ---------------------------------------------------------------
// part of callingLib.dll
// moduleCalling.h
#include "moduleCalled.h"
class classCalling {
  public:
    classCalled* ref;
    void justSomeMethod();
};
// ---------------------
// moduleCalling.cpp
#include "moduleCalling.h"
void classCalling::justSomeMethod() {
  ref = new classCalled();
  int a = ref->methodCalled(); // <--- this is not allowed by linker,
                               // unless methodCalled is made virtual.
}

链接器链接来自不同模块的代码片段。如果从一个模块调用到另一个模块,链接器必须知道要调用的函数是在哪个其他模块中实现的,并将调用替换为实际地址。这是一幅非常粗略的画面,但足以了解正在发生的事情。

在您的情况下,链接器必须知道您的函数位于 calledLib.dll 中。因此,您必须链接到称为Lib.dll的东西。这称为导入库。它的名字应该叫Lib.lib。为了生成它,您应该编写一个 .def 文件,但对于类方法来说很难,因为链接器使用的类方法名称看起来与它们在C++代码中的外观大不相同。或者您可以使用 declspecs。它将生成正确的 calledLib.lib,您必须将其与您的 callingLib.dll 链接。