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

C++ LNK2001:尝试从另一个DLL调用对象的方法时,未解析的外部符号,c++,visual-c++,dll,lnk2001,C++,Visual C++,Dll,Lnk2001,我有两个模块,每个模块都有自己的类和对象。每个模块都编译成一个DLL。我想进行“交叉DLL”方法调用,使指针指向另一个类的对象,但链接器不允许这样做(MSVC++2008) 更具体地说: 有calledModule.cpp,它有calledClass和这个类的对象(calledObject);类调用了Method,我想调用它;模块被编译为DLL并成为(令人惊讶的!)名为dlib.DLL 有callingModule.cpp,它有callingClass;除其他外,该类具有属性,该属性是指向ca

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

更具体地说:

  • 有calledModule.cpp,它有calledClass和这个类的对象(calledObject);类调用了Method,我想调用它;模块被编译为DLL并成为(令人惊讶的!)名为dlib.DLL
  • 有callingModule.cpp,它有callingClass;除其他外,该类具有属性,该属性是指向calledObject的指针;模块编译成DLL callingLib.DLL;calledObject上的指针在构造函数中设置
我能够编译整个代码。当链接器启动时,麻烦就来了。我得到以下信息: moduleCalling.obj:错误LNK2001:未解析的外部符号“public:void\u thiscall classCalled::methodCalled…”

我不使用任何declspec东西,因此没有从calledLib.dll导出任何东西

我正在调用的方法(methodCalled)存在于实现中,它的原型在标头中正确声明。被调用的类是一个“基本”类,不是从任何东西继承的。 此外,当我将methodCalled声明为虚拟时,整个项目都编译并正常工作

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

附言:我正在使用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的一部分
//moduleCalled.h
类名为{
公众:
int methodCalled(){return 1};
};
// ---------------------------------------------------------------
//callingLib.dll的一部分
//模壳
#包括“moduleCalled.h”
类调用{
公众:
类称为*ref;
void justSomeMethod();
};
// ---------------------
//ModuleCaling.cpp
#包括“moduleCalling.h”
void classCalling::justSomeMethod(){
ref=新类调用();

int a=ref->methodCalled();//链接器链接来自不同模块的代码片段。如果您有一个从一个模块到另一个模块的调用,链接器必须知道您调用的函数是在哪个模块中实现的,并用实际地址替换调用。这是一个非常粗略的图,但足以理解发生了什么


在您的情况下,链接器必须知道您的函数位于calledLib.dll中。因此,您必须链接到引用calledLib.dll的对象。这一对象称为导入库。它的名称应为calledLib.lib。为了生成它,您应该编写一个.def文件,但对于类方法来说很困难,因为类方法链接器使用的名称看起来与C++代码中的外观非常不同。或者可以使用DeCuScript。它将生成适当的CaleDeL.LIB,您必须与CalpIdLILIB .DLL.< /P>链接。如果不至少看到代码片段,或者有一些问题来说明问题,那么很难回答。如何命名模块类博览会?rted/imported?关于导出没有什么特别的。我不使用任何declspec或类似的。实际代码非常大和复杂,所以我尝试用一种通用的方式来总结这个问题。你没有declspec?那么你的符号是如何跨模块导出/导入的?我不认为这是一个问题。我使用了declspec,但没有帮助。不过,making it“virtual”在某种程度上有所帮助。您需要了解如何通过生成的.LIB文件将符号导出Microsoft DLL。Declspec是一种方法。在.DEF输入文件中硬编码方法/函数/数据是另一种方法。如果您使用基类作为“接口”,您可以访问其他DLL中的虚拟方法,只要这些其他DLL在进行虚拟调用之前已预加载。我明白了,谢谢!calledLib.lib是缺少的链。我看到在添加依赖项后,链接器命令行中提到了calledLib.lib,尽管calledLib是一个动态库。现在很清楚,为什么它是还有一件事:uu declspec(dllexport)实际上很有帮助……我无意中将它放在了另一个名称非常相似的方法中。在将它放在正确的函数中之后,会生成.lib并链接所有内容。