Thread: Hopefully simple 'unresolved external symbol' problem

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    9

    Hopefully simple 'unresolved external symbol' problem

    I have an object that gets a list of 'Messages' (in std::string format) and it has to convert part of the string into either an int or a double. I found code online that appears to do this. The problem is that I'm getting unresolved external symbol errors. I think they have something to do with the fact a function is a template, but I'm not sure.

    StringToAnyType() is the function I found, everything else I wrote

    The header
    Code:
    //MessageReceiver.h
    
    //Receives Messages from InternalMessageService
    
    #include<vector>
    #include<string>
    #include<sstream>
    
    class MessageReceiver
    {
    protected:
    	int TranslateIntMessage(std::string sMessage);  //returns the int part of the message
    	double TranslateDoubleMessage(std::string sMessage); //returns the double part of the message
    	std::string TranslateStringMessage(std::string sMessage);
    
    	std::vector<std::string>* MessagesReceived; // DO NOT DELETE pointer points to list on IMS
    	int NumMessRec;
    
    	template <class G>
    
    	void StringToAnyType(G& t, std::string inString);
    	std::string StringParser(std::string sMessage);
    
    };
    the cpp file

    Code:
    #include "MessageReceiver.h"
    
    template <class G>
    void StringToAnyType(G& t, std::string inString) //turns the string into ints or doubles
    {
        std::stringstream ss(inString);
        ss >> t;
    }
    
    std::string StringParser(std::string sMessage) //returns just the number part of the string
    {
    	int NumSpace = 0;
    	int iter = 0;
    	
    	for (iter = 0; iter < sMessage.length(); ++iter)
    	{
    		if (NumSpace == 2)
    		{
    			break;
    		}
    		if (sMessage[iter] == ' ')
    		{
    			NumSpace++;
    		}
    	}
    
    	if (NumSpace != 0)
    	{
    		//raise error
    		return 0;
    	}
    
    	sMessage.erase(0,iter);
    	return sMessage;
    }
    
    int MessageReceiver::TranslateIntMessage(std::string sMessage)
    {
    	sMessage = StringParser(sMessage);
    
    	int iReturnInt = 0;
    	const int& Return = iReturnInt;
    
    	StringToAnyType(Return, sMessage);
    	return iReturnInt;
    }
    
    double MessageReceiver::TranslateDoubleMessage(std::string sMessage)
    {
    	sMessage = StringParser(sMessage);
    
    	double iReturnDouble = 0;
    
    	StringToAnyType(iReturnDouble, sMessage);
    	return iReturnDouble;
    }
    
    std::string TranslateStringMessage(std::string sMessage)
    {
    	sMessage = StringParser(sMessage);
    	return sMessage;
    }
    the errors (curse their longness )
    Code:
    MessageReceiver.obj : error LNK2019: unresolved external symbol "protected: void __thiscall MessageReceiver::StringToAnyType<int const >(int const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??$StringToAnyType@$$CBH@MessageReceiver@@IAEXABHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "protected: int __thiscall MessageReceiver::TranslateIntMessage(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?TranslateIntMessage@MessageReceiver@@IAEHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
    MessageReceiver.obj : error LNK2019: unresolved external symbol "protected: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall MessageReceiver::StringParser(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?StringParser@MessageReceiver@@IAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V23@@Z) referenced in function "protected: int __thiscall MessageReceiver::TranslateIntMessage(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?TranslateIntMessage@MessageReceiver@@IAEHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
    MessageReceiver.obj : error LNK2019: unresolved external symbol "protected: void __thiscall MessageReceiver::StringToAnyType<double>(double &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??$StringToAnyType@N@MessageReceiver@@IAEXAANV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "protected: double __thiscall MessageReceiver::TranslateDoubleMessage(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?TranslateDoubleMessage@MessageReceiver@@IAENV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
    I'm sure it's something simple, but it doesn't appear to be anything I've run into before

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    In the .cpp file, the functions you have a functions, like "StringParser", that should be "MessageReceiver::StringParser".

    After fixing that, I was getting errors in the function
    Code:
    template <class G>
    void StringToAnyType(G& t, std::string inString) //turns the string into ints or doubles
    {
        std::stringstream ss(inString);
        ss >> t;
    }
    on the line "ss >> t;". From the error message ("ambiguous overload operator >>"), or something similar, it seems that its possible to pass a type G that doesn't overload the ">>" operator (my guess). If you know that the type of "G" will be one of "int" or "double", then just overload the function, one for each type.

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    9
    Oh my, don't I feel embarrassed. :3 It's always something easy. The MessageReceiver:: thing solved it. I don't know why you had problems with ss>>t. It seems to work with both vc++ express and Dev-c++, but if I run into that problem, I'll take your advice. Thank you!

  4. #4
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    I was using G++ and it was giving errors. Maybe I was doing something wrong to get that error, but I dont think I changed anything besides what I've told you. What you can try out is to create some trivial class, and do not override the ">>" operator, and try to call the "StringToAnyType" function on an instance of that class and see if you get a runtime error. And no problem for helping!

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    9
    Wow I suck at this, I tried a simple class and I got a similar linker error to the one I got before :,(

    here's the main

    Code:
    #include "MessageReceiver.h"
    
    
    #include<iostream>
    #include<string>
    
    
    class Bub
    {public:
    	std::string cat;
    };
    
    int main()
    {
    	
    	MessageReceiver MRReceiver;
    
    
    	char* sTest = "Test Word\0";
    	std::string sMsg = "MSG\0";
    
    	Bub dog;
    	MRReceiver.StringToAnyType<Bub>(dog, sMsg);
    
    	std::cout << dog.cat;
    
    
    	std::cin.get();
    
    
    	return 0;
    }
    the MessageReceiver class is the same except everything is 'public' (could that be the problem?

    error here
    Code:
    main.obj : error LNK2019: unresolved external symbol "public: void __thiscall MessageReceiver::StringToAnyType<class Bub>(class Bub &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??$StringToAnyType@VBub@@@MessageReceiver@@QAEXAAVBub@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main

  6. #6
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Instead of "Bub", make it a "stringstream" (so "#include<sstream>"). If it gets rid of the error, then you have to refer to my post above about the possibility of not overriding the ">>" operator.

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    9
    'stringstream' doesn't work; ie "dog" is now a stringstream object. It doesn't matter too much, unless the error is related to another error I have when I tried to test the complete subsystem.

    It might warrant a new thread because it's a different error, but I'll ask you here first. One of the member variables of an object is reported as either a CXX030 or a CXX0017 (depending on whether the object is referred to as a reference or a pointer) by the debugger (vc++ express). I'd show you code, but its 7 files, including' MessageReceiver'.
    What are causes to CXX030 and CXX0017? If I choose the variable in such a way, the debugger shows the correct values, but the program still crashes when it tries to use the 'other' variable. Sorry if this is confusing.

  8. #8
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    I dont know about those CXX things. My guess is that they're either Visual C++ error codes or some internal thing that you can't do anything about.

    Post your updated MessageReceiver.h and MessageReceiver.cpp and another copy of the test, similar to the one you have above with the "Dog" example. Without the complete code its pretty difficult to help.

  9. #9
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    With most compilers, templated code has trouble when it's separated out of the header file. Take the StringToAny function out of the source file and put it in the header file. Then recompile/link and see if that works.

    When you compile a templated function in a source file, nothing happens, there is nothing to compile. When you link, there is no StringToAny function compiled anywhere for it to find so it spits out the error. If you instead put that function's code in the header (which gets included in your other source files), then those source files where you use the function can build the code for the function based on the type your passing in at the moment of compilation.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  10. #10
    Registered User
    Join Date
    Jan 2009
    Posts
    9
    at hk_mp5kpdw
    moving the templated code to the header worked

    at nadroj
    it raises an error when 'Bub' classs is used. For now though, I only anticipate using the basic data types with this system, so I'll leave as is. I'll write a comment to remind myself of the problems with g++ and the code so that in the future, if I, or anyone else tries to use my code with g++, they're know where the problem is at.

    For now, I have to track down why the subsystem crashes. I.E. The 'message sender' encodes the message, the 'Message Service' holds the messages, and the 'receiver' decodes the messages. For that I think needs a new thread as it as nothing to do with the thread title of this one.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Unresolved External Symbol?
    By AYT in forum C Programming
    Replies: 3
    Last Post: 06-11-2009, 07:05 PM
  2. wxWidgets link problem
    By cboard_member in forum C++ Programming
    Replies: 2
    Last Post: 02-11-2006, 02:36 PM
  3. unresolved external symbol
    By jixig in forum C++ Programming
    Replies: 3
    Last Post: 01-16-2005, 07:56 PM
  4. Linker errors...
    By MipZhaP in forum Game Programming
    Replies: 2
    Last Post: 08-27-2004, 09:12 AM
  5. Ask about these "unresolved external symbol" error
    By ooosawaddee3 in forum C++ Programming
    Replies: 1
    Last Post: 06-29-2002, 11:39 AM