1

I have an << operator overload defined in a (VC++ 2013) DLL that compiles fine:

Definition:

__declspec(dllexport)  friend std::ostream& operator<< (std::ostream& os, const ComplexMessage& rhs);

Implementation:

std::ostream& operator<< (std::ostream& os, const ComplexMessage& rhs)
{
   os << rhs.toString();
   return(os);
}

The dll contains another 50 methods including multiple operator overloads, which compile and link fine.

However, the program using the dll can't link the method for <<.

It declares the << overload as

__declspec(dllimport) std::ostream& operator<< (std::ostream& os, const ComplexMessage& rhs);

The code compiles fine. But it won't link:

error LNK2001: unresolved external symbol "__declspec(dllimport) class std::basic_ostream > & __cdecl messaging::operator<<(class std::basic_ostream > &,class messaging::ComplexMessage const &)"

All other DLL methods link fine. Does anyone know why this linker error is occurring?

EDIT This is different than the proposed duplicate question. The symbols are defined in the code of the DLL and syntactically compile; however, it doesn't link. This suggests to me that either the code for that particular operator<< overload is not being generated, or it is being generated but not correctly found. I'm sure it's something simple, but I've been banging my head on this one.

NoCake
  • 84
  • 7
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White May 03 '16 at 03:20
  • might catch something if you specify the unnamed namespace `::operator<<` in both locations. That's one issue I've seen is a prototype in a namespace, and the definition in another/none. That won't give compile errors. (Will likely give warnings, though. Have you sifted through all of your warnings?) To be clear, this won't fix it, but might help diagnose it. – Jfevold May 03 '16 at 03:32
  • Use a .h file to declare exported functions. That way you can't accidentally use the wrong namespace name. Crystal ball says that it is not defined in *messaging*. – Hans Passant May 03 '16 at 13:59
  • The answer was indeed the namespace, and not a class identifier. Prefixing "messaging:;" to the operator ("messaging::operator<<") resolved it. – NoCake May 03 '16 at 20:36

1 Answers1

2

Thanks to the input above it was determined the solution was to explicitly specify the namespace in the implementation (not the definition):

std::ostream& messaging::operator<< (std::ostream& os, const ComplexMessage& rhs);

Note that having a "using namespace messaging" clause had no effect; the linker requires this be explicitly specified in the implementation declaration.

NoCake
  • 84
  • 7