Search code examples
c++dlllnk2019

Unresolved external when trying to link against a dll


I'm trying to link against a dll that I have all the source for, but I can't get access to a dirt simple class I've created in it without getting LNK2019's.

I made this:

class makeprob
{
public:
    makeprob();
    ~makeprob();
};

with the implementation:

makeprob::makeprob() { }
makeprob::~makeprob() { }

as a nice simple template. Then in my actual project, I have the following:

#include "evil_dll.h"

class PC
{
public:
    PC() { };
    ~PC() { };

    static makeprob ProblemCreator;
};

with the implementation:

#include "evil_dll.h"

makeprob PC::ProblemCreator;

When I then try to link against it and construct a makeprob class, I get

LNK2019 unresolved external symbol "public: __thiscall makeprob::makeprob(void)" (??0makeprob@@QAE@XZ) referenced in function "void __cdecl `dynamic initializer for 'public: static class makeprob PC::ProblemCreator''(void)" (??__E?ProblemCreator@PC@@2Vmakeprob@@A@@YAXXZ)

I've checked that I'm linking against the lib and I am. From everything I can tell, the dll is a 32 bit dll to go with my 32 bit app. I am already using functions from the dll, but they've been declared with __declspec(dllimport)

I have to admit; I'm all thumbs with this. I have no idea if I'm supposed to do anything specific on the receiver to bring a class across from a dll. This is part of a school test, and part of the instructions tell me I don't need to edit the source code (just use the provided classes). I only created the makeprob class to make the problem simple to post up here.

Any advice would be invaluable! Thank you so much!


Solution

  • Scheff actually answers this in the comments above, just formalizing it for Stack Overflow, but Scheff deserves all the cool-haircut-and-rayban-sunglasses points.

    My problem is the class implementation doesn't export the constructor or destructor. My makeprob header file above should read like this:

    class makeprob
    {
    public:
        __declspec(dllexport) makeprob();
        __declspec(dllexport) ~makeprob();
    };
    

    to have access to those. Scheff further suggests using macros for this (which I have found they already exist: systemAPI) instead of writing it out manually.

    This doesn't get around my professor telling me I don't need to edit the source, but since all the other functions of the class I'm importing have systemAPI in front of them, and only the constructor and destructor don't, I'm gonna call it an oversight? Unless there is a fancy way to import a class without its constructor/destructor.

    Thanks everyone!