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

StackOverflow https://stackoverflow.com/questions/14628945

  •  06-03-2022
  •  | 
  •  

Frage

I have two modules, each with own class and with own object. Each module is compiled to a DLL. I want to make a "cross-DLL" method call, having pointer to the object of another class, but linker doesn't allow to do this (MSVC++ 2008).

More specifically:

  • there is calledModule.cpp, that has calledClass, and object of this class (calledObject); class has calledMethod, which I want to call; module is compiled to DLL and becomes (surprise!) calledLib.dll.
  • there is callingModule.cpp, that has callingClass; among other things, the class has the attribute, which is a pointer to the calledObject; module is compiled to DLL callingLib.dll; the pointer on calledObject is set in the constructor.

I'm able to compile the whole code. The trouble comes when the linker starts. I'm getting the following: moduleCalling.obj : error LNK2001: unresolved external symbol "public: void __thiscall classCalled::methodCalled ..."

I don't use any declspec things, so nothing is exported from the calledLib.dll.

The method that I'm calling (methodCalled) is present in the implementation, its prototype is correctly declared in header. The classCalled is a "basic" class, not inherited from anything. Moreover, the whole project compiles and working correctly, when I declare methodCalled as a virtual...

I have troubles understanding, why I can't call the method of the object in a "normal" way from another DLL? Why declaring it as a "virtual" helps? Anyone knows? I have some guesses, but expert answer will help a lot to understand this stuff.

P.S.: I'm using MSVC++ 2008.

Thanks!

Update: adding code snippet, which reflects, how the code looks like.

// 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.
}
War es hilfreich?

Lösung

Linker links pieces of code from various modules. If you have a call from one module to another, linker has to know in which other module the function you're invoking is implemented and substitute the call by the real address. This is a very rough picture, but it's enough to understand what is going on.

In your case the linker has to know that your function is located in calledLib.dll. Therefore you have to link with something that refers to calledLib.dll. This something is called an import library. It's name should be calledLib.lib. In order to generate it you either should write a .def file, but it's difficult for class methods, since class methods names used by linker look very different from what they look like in your C++ code. Or you can use declspecs. It will generate the proper calledLib.lib, which you will have to link with your callingLib.dll.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top