Search code examples
c++dllstlstdlist

Unresolved External Symbol using std::list in a dll


I am trying to learn basics of building a library and DLLs. I have built a simple DLL using MSVC and i can use it in simple console applications via linking.

#if defined(DUMMYCLASS_EXPORT)
#define DUMMYCLASS_API __declspec(dllexport)
#else
#define DUMMYCLASS_API __declspec(dllimport)
#endif

#include <string>
#include <list>

class DUMMYCLASS_API DummyClass
{
public:
    DummyClass(int id, const std::string& name);
    friend std::list<DummyClass>& operator<<(std::list<DummyClass>& dl, const DummyClass& dc);
    void ID(const int newID);
    const int ID();
    void Name(const std::string newName);
    const std::string Name();
private:
    int id;
    std::string name;
};

After that i tried to build another DLL which depends on the first DLL i built. Below is the header file of that new class.

#pragma once
#if defined(DUMMYWRAPPER_EXPORT)
#define DUMMYWRAPPER_API __declspec(dllexport)
#else
#define DUMMYWRAPPER_API __declspec(dllimport)
#endif

#include <list>
#include "DummyClass.h"

class DUMMYWRAPPER_API DummyWrapper
{
public:
    DummyWrapper();
    ~DummyWrapper();
    DummyWrapper& operator<<(const DummyClass& dc);
private:
    std::list<DummyClass>* dList;
};

I added DummyClass.dll and .lib to my new project but when i try to build it i get an error

Error   1   error LNK2001: unresolved external symbol "class
std::list<class DummyClass,class std::allocator<class DummyClass> > &
__cdecl operator<<(class std::list<class DummyClass,class std::allocator<class DummyClass> > &,class DummyClass const &)"
(??6@YAAAV?$list@VDummyClass@@V?$allocator@VDummyClass@@@std@@@std@@AAV01@ABVDummyClass@@@Z)    c:\Users\MCE\documents\visual
studio 2013\Projects\DummyWrapperDLL\DummyWrapperDLL\DummyWrapper.obj   DummyWrapperDLL

Right now I don't know what to search for and all my searches end up with somewhat easier and non-relevant linking errors. How do i fix this one?

EDIT: Here s DummyClass.cpp

#define DUMMYCLASS_EXPORT
#include "DummyClass.h"
#include <iostream>
#include <stdio.h>

DummyClass::DummyClass(int newid, const std::string& newname)
    :id(newid), name(newname)
{
    std::cout << "Dummy Object created" << std::endl;
    std::cout << "ID: " << id << " / Name: " << name << std::endl;
}

std::list<DummyClass>& operator<<(std::list<DummyClass>& dl, const DummyClass& dc)
{
    dl.push_back(dc);
    return dl;
}

void DummyClass::ID(int newID)
{
    this->id = newID;
    std::cout << "ID changed to " << newID << std::endl;
}

const int DummyClass::ID()
{
    return this->id;
}

void DummyClass::Name(std::string newName)
{
    this->name = newName;
    std::cout << "Name changed to " << newName << std::endl;
}

const std::string DummyClass::Name()
{
    return this->name;
}

And this one is DummyWrapper.cpp

#define DUMMYWRAPPER_EXPORT
#include "DummyWrapper.h"

DummyWrapper::DummyWrapper()
{
    dList = new std::list<DummyClass>;
}


DummyWrapper::~DummyWrapper()
{
    dList->clear();
    dList = nullptr;
}

DummyWrapper& DummyWrapper::operator<<(const DummyClass& dc)
{
    *dList << dc;
    return *this;
}

I also tried giving them different export names but that doesnt work either.


Solution

  • Declare the operator << of the DummyClass before the DummyClass and explicitly export it.

    The name lookup rules means that the function can be found during compile time, but since the function is not actually a member of the class it is not exported as part of the class, hence the link fails.

    Alternatively, don't make it a friend, rather make it a member method.