|
Boost : |
From: Ashok Thirumurthi (athirumurthi.news_at_[hidden])
Date: 2005-11-10 13:10:14
Dear Boost,
Could I trouble the list with a question that may be no more than my programming error?
I am using VC++7.1 with the boost.signals 1_33_0 library. I successfully wrote a class to wrap custom signals. Upon generalizing the class as a template, VC++ reports unresolved externals. My predicament is that I am unable to match a mangled name of a template instance with the signals library export. What does one do in this case other than identify the problem by inspection?
For instance, given a link error that includes a mangled name such as:
?ConnectToNotify@?$TQueryNotifyEvent_at_V?$signal@$$A6AKAAVCChromaBoostData_at_Ashok@@@ZU?$last_value_at_K@boost@@HU?$less_at_H@std@@V?$function@$$A6AKAAVCChromaBoostData_at_Ashok@@@ZV?$allocator_at_X@std@@@4@@boost@@V?$slot_at_V?$function@$$A6AKAAVCChromaBoostData_at_Ashok@@@ZV?$allocator_at_X@std@@@boost@@@2_at_VCChromaBoostData@Ashok@@@Ashok@@QAEAAVconnection_at_signals@boost@@ABV?$slot_at_V?$function@$$A6AKAAVCChromaBoostData_at_Ashok@@@ZV?$allocator_at_X@std@@@boost@@@5@@Z
What mangled name in the dumpbin output for the boost library should I look for? Even with the promise of undname.exe, the template instantiation makes it difficult to identify the export that I'm not matching.
The above unresolved external was referenced by the call to ConnectToNotify in the namespace Ashok:
if (CChromaBoostEvent* pNotify = dynamic_cast <CChromaBoostEvent*> (pEventMgr->GetObject (kEvent_ChromaBoost)))
{
pNotify->ConnectToNotify (boost::bind (&CChromaBoostSlot::OnNotifyChromaBoost, this, _1)); // LNK2019
}
However, the link error doesn't occur if CChromaBoostEvent is a class. It does occur if CChromaBoostEvent is an instance of a TQueryNotifyEvent template. More specifically:
*****************************
Here's what does work:
*****************************
struct strChromaBoostData
{
strChromaBoostData () : m_nCBoosterLevel (0), m_nCAutoBoosterLevel (-1), m_bBoostForPeople (true) {}
int m_nCBoosterLevel;
int m_nCAutoBoosterLevel;
bool m_bBoostForPeople;
};
#define NKNEF_ENTRY __declspec(dllexport)
class NKNEF_ENTRY CChromaBoostEvent : public CImageEvt
{
typedef boost::signal<NKRESULT (const strChromaBoostData&), maximum<NKRESULT> > sigNotify_ChromaBoost;
public:
CChromaBoostEvent ();
virtual ~CChromaBoostEvent ();
boost::signals::connection & ConnectToNotify (const sigNotify_ChromaBoost::slot_type& slot);
private:
sigNotify_ChromaBoost sigNotify;
boost::signals::connection conNotify;
};
boost::signals::connection & ConnectToNotify(const sigNotify_ChromaBoost::slot_type & slot)
{
return (conNotify = sigNotify.connect (slot));
}
*****************************
Here's what doesn't work:
*****************************
template <class TSignal, class TSlot, class TData>
class NKNEF_ENTRY TQueryNotifyEvent : public CImageEvt
{
public:
TQueryNotifyEvent ();
virtual ~TQueryNotifyEvent ();
boost::signals::connection & ConnectToNotify (const TSlot & slot);
private:
TSignal sigNotify;
boost::signals::connection conNotify;
};
class CChromaBoostData
{
public:
CChromaBoostData () : m_nCBoosterLevel (0), m_nCAutoBoosterLevel (-1), m_bBoostForPeople (true) {}
int m_nCBoosterLevel;
int m_nCAutoBoosterLevel;
bool m_bBoostForPeople;
};
typedef boost::signal<NKRESULT (CChromaBoostData&)> CChromaBoostSignal;
typedef TQueryNotifyEvent <CChromaBoostSignal, CChromaBoostSignal::slot_type, CChromaBoostData> CChromaBoostEvent;
template <class TSignal, class TSlot, class TData>
boost::signals::connection & TQueryNotifyEvent<TSignal, TSlot, TData>::ConnectToNotify(const TSlot & slot)
{
return (conNotify = sigNotify.connect (slot));
}
Thanks for your thoughts,
- Ashok Thirumurthi
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk