Jump to content

  • Log In with Google      Sign In   
  • Create Account


Odd unresolved external symbol to nonexistent constructor


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 incertia   Crossbones+   -  Reputation: 777

Like
0Likes
Like

Posted 17 August 2013 - 02:16 PM

So once upon a time I wrote an interface
 
struct IC_API Infinity::IEventManager {
	virtual INFINITY_VOID	INFINITY_CALL	AttachEventListener(INFINITY_GUID EventID, EventCallback_t f) = 0;
	virtual INFINITY_VOID	INFINITY_CALL	DetachEventListener(INFINITY_GUID EventID, EventCallback_t f) = 0;			//maybe with std::find?
	virtual INFINITY_VOID	INFINITY_CALL	TriggerEvent(IEvent *e) = 0;
};
and something that implemented that interface in another project
class CEventManager : public Infinity::IEventManager {
public:
	CEventManager() {}
	~CEventManager() {}

	//GUID comparison functor
	typedef struct {
		bool operator()(const INFINITY_GUID &left, const INFINITY_GUID &right){
			if(left.Data1 < right.Data1) return true;
			if(left.Data2 < right.Data2) return true;
			if(left.Data3 < right.Data3) return true;
			for(register size_t i = 0; i < 8; i++)
				if(left.Data4[i] < right.Data4[i]) return true;
			return false;
		}
	} GUIDComparer;

	virtual INFINITY_VOID		INFINITY_CALL	AttachEventListener(INFINITY_GUID EventType, Infinity::EventCallback_t f){
		//Just insert it
		event_map[EventType].insert(f);
	}

	virtual INFINITY_VOID		INFINITY_CALL	DetachEventListener(INFINITY_GUID EventType, Infinity::EventCallback_t f){
		//See if the event type has any listeners
		auto it = event_map.find(EventType);
		if(it != event_map.end()){
			//If so, see if it has our listener function
			auto func_it = it->second.find(f);
			if(func_it != it->second.end()){
				//Then remove it
				it->second.erase(func_it);
			}
		}
	}

	virtual INFINITY_VOID		INFINITY_CALL	TriggerEvent(Infinity::IEvent *e){
		//Launch listeners
		INFINITY_GUID magic = e->GetEventType();
		std::for_each(event_map[magic].begin(), event_map[magic].end(), [&] (Infinity::EventCallback_t f) -> INFINITY_VOID { f(e); });

		delete e;		//Because it's called with something like TriggerEvent(new IEvent(...));
	}
private:
	//Global event listener storage for each event
	//Maps (GUID EventType) -> set of listener functions
	std::map<INFINITY_GUID, std::set<Infinity::EventCallback_t>, GUIDComparer> event_map;
};
except I'm getting an unresolved external symbol to an undefined constructor:
 
error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall Infinity::IEventManager::IEventManager(void)" (__imp_??0IEventManager@Infinity@@QAE@XZ) referenced in function "public: __thiscall CEventManager::CEventManager(void)" (??0CEventManager@@QAE@XZ)
 

Any ideas on what could be causing this problem?

Edited by incertia, 17 August 2013 - 02:19 PM.

what

Sponsor:

#2 King Mir   Members   -  Reputation: 1934

Like
0Likes
Like

Posted 17 August 2013 - 04:07 PM

Are you properly including the definition of Infinity::IEventManager prior to the class deriving from it?

#3 Cosmic314   Members   -  Reputation: 1169

Like
1Likes
Like

Posted 17 August 2013 - 04:14 PM

I'm going to guess you need a virtual destructor defined in your Infinity::IEventManager interface:

struct IC_API Infinity::IEventManager {
	virtual INFINITY_VOID	INFINITY_CALL	AttachEventListener(INFINITY_GUID EventID, EventCallback_t f) = 0;
	virtual INFINITY_VOID	INFINITY_CALL	DetachEventListener(INFINITY_GUID EventID, EventCallback_t f) = 0;			//maybe with std::find?
	virtual INFINITY_VOID	INFINITY_CALL	TriggerEvent(IEvent *e) = 0;
        virtual ~IEventManager() {} 
};


#4 incertia   Crossbones+   -  Reputation: 777

Like
0Likes
Like

Posted 17 August 2013 - 05:48 PM

Are you properly including the definition of Infinity::IEventManager prior to the class deriving from it?

Yes I am.
 

I'm going to guess you need a virtual destructor defined in your Infinity::IEventManager interface:

struct IC_API Infinity::IEventManager {
	virtual INFINITY_VOID	INFINITY_CALL	AttachEventListener(INFINITY_GUID EventID, EventCallback_t f) = 0;
	virtual INFINITY_VOID	INFINITY_CALL	DetachEventListener(INFINITY_GUID EventID, EventCallback_t f) = 0;			//maybe with std::find?
	virtual INFINITY_VOID	INFINITY_CALL	TriggerEvent(IEvent *e) = 0;
        virtual ~IEventManager() {} 
};

Adding and defining a virtual destructor like that gives me yet another unresolved external error.
what

#5 Pink Horror   Members   -  Reputation: 1117

Like
0Likes
Like

Posted 17 August 2013 - 09:04 PM

Either your constructor is not being exported from its DLL, or you are not linking properly to your other project. I think, if you explicitly declare the constructor and implement it in a cpp file, you'll be able to make sure it gets exported.



#6 incertia   Crossbones+   -  Reputation: 777

Like
0Likes
Like

Posted 18 August 2013 - 10:02 AM

So I realized that exporting interfaces from a DLL made no sense... not exporting it made everything work.
what

#7 Cosmic314   Members   -  Reputation: 1169

Like
0Likes
Like

Posted 18 August 2013 - 02:13 PM

Your post had me curious about DLL exports.  Apparently if you wanted to just define an interface in a DLL you can create an empty .cpp module that simply includes your interface definition.  I didn't get a chance to try it though.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS