I am working on a code base using Root 5.28, building with VS2008. I am trying to inherit from some GUI controls in the application to extend their functionalities. I have started with TGNumberEntry and TGNumberEntryField, changing them so that the TGNumberEntry or TGNumberEntryField owns a unique ID which can later be queried for. I have also overridden TGNumberEntryField::SetNumber() so that after calling the parent class’s version, I can do some other work. There is more functionality to be added but this is the only functionality I added so far, and it is shown in the example code below. I have included the header file in the cpp file for the MyMainWindow class, and added member pointer variables, both of type TGNumberEntryField. The project compiles without a problem, but I get the following linker errors:
error LNK2001: unresolved external symbol "public: virtual void __thiscall MyNumberEntryField::ShowMembers(class TMemberInspector &)" (?ShowMembers@MyNumberEntryField@@UAEXAAVTMemberInspector@@@Z)
error LNK2001: unresolved external symbol "public: virtual void __thiscall MyNumberEntryField::Streamer(class TBuffer &)" (?Streamer@MyNumberEntryField@@UAEXAAVTBuffer@@@Z)
error LNK2019: unresolved external symbol "public: static class TClass * __cdecl MyNumberEntryField::Class(void)" (?Class@MyNumberEntryField@@SAPAVTClass@@XZ) referenced in function "public: virtual class TClass * __thiscall MyNumberEntryField::IsA(void)const " (?IsA@MyNumberEntryField@@UBEPAVTClass@@XZ)
error LNK2001: unresolved external symbol "public: virtual void __thiscall MyNumberEntry::ShowMembers(class TMemberInspector &)" (?ShowMembers@MyNumberEntry@@UAEXAAVTMemberInspector@@@Z)
error LNK2001: unresolved external symbol "public: virtual void __thiscall MyNumberEntry::Streamer(class TBuffer &)" (?Streamer@MyNumberEntry@@UAEXAAVTBuffer@@@Z)
error LNK2019: unresolved external symbol "public: static class TClass * __cdecl MyNumberEntry::Class(void)" (?Class@MyNumberEntry@@SAPAVTClass@@XZ) referenced in function "public: virtual class TClass * __thiscall MyNumberEntry::IsA(void)const " (?IsA@MyNumberEntry@@UBEPAVTClass@@XZ)
error LNK2019: unresolved external symbol "class ROOT::TGenericClassInfo * __cdecl ROOT::GenerateInitInstance(class MyNumberEntryField const *)" (?GenerateInitInstance@ROOT@@YAPAVTGenericClassInfo@1@PBVMyNumberEntryField@@@Z) referenced in function "void __cdecl ROOT::`dynamic initializer for 'R__dummyintdefault6''(void)" (??__ER__dummyintdefault6@ROOT@@YAXXZ)
error LNK2019: unresolved external symbol "class ROOT::TGenericClassInfo * __cdecl ROOT::GenerateInitInstance(class MyNumberEntry const *)" (?GenerateInitInstance@ROOT@@YAPAVTGenericClassInfo@1@PBVMyNumberEntry@@@Z) referenced in function "void __cdecl ROOT::`dynamic initializer for 'R__dummyintdefault7''(void)" (??__ER__dummyintdefault7@ROOT@@YAXXZ)
I have tried everything I can think of, looking down into Root code, but haven’t been able to figure this issue out. I am not yet well enough versed in how ClassDef stuff works in Root, so I am certain I am missing some small thing. While I continue digging, I am posting this to see if anyone has an idea of what I should look at in order to fix the issue. Thanks for any help. The code for my new classes (given as MyNumberEntry and MyNumberEntryField) is shown below:
MyNumberEntry.h:
#ifndef MY_NUMBER_ENTRY_H
#define MY_NUMBER_ENTRY_H
#include "Rtypes.h"
#include "Windows4Root.h"
#include "TGNumberEntry.h"
class MyNumberEntryField : public TGNumberEntryField
{
public:
MyNumberEntryField(const TGWindow *p, Int_t id,
Double_t val, GContext_t norm,
FontStruct_t font = GetDefaultFontStruct(),
UInt_t option = kSunkenFrame | kDoubleBorder,
Pixel_t back = GetWhitePixel());
MyNumberEntryField(const TGWindow *parent = 0,
Int_t id = -1, Double_t val = 0,
EStyle style = kNESReal,
EAttribute attr = kNEAAnyNumber,
ELimit limits = kNELNoLimits,
Double_t min = 0, Double_t max = 1);
~MyNumberEntryField() { }
virtual void SetNumber(Double_t val);
void SetObjID(int id) { m_iObjId = id; }
int GetObjID() { return m_iObjId; }
private:
int m_iObjId;
public:
ClassDef(MyNumberEntryField,0) // Entry field widget for several numeric formats (wraps TGNumberEntryField)
};
class MyNumberEntry : public TGNumberEntry
{
public:
MyNumberEntry(const TGWindow *parent = 0, Double_t val = 0,
Int_t digitwidth = 5, Int_t id = -1,
EStyle style = kNESReal,
EAttribute attr = kNEAAnyNumber,
ELimit limits = kNELNoLimits,
Double_t min = 0, Double_t max = 1);
~MyNumberEntry() { }
void SetObjID(int id) { fNumericEntry->SetObjID(id); }
int GetObjID() { return fNumericEntry->GetObjID(); }
MyNumberEntryField *GetNumberEntry() const {
// Get the number entry field
return fNumericEntry;
}
protected:
MyNumberEntryField *fNumericEntry; // Number text entry field
public:
ClassDef(MyNumberEntry,0) // Entry field widget for several numeric formats (wraps TGNumberEntry)
};
#endif // MY_NUMBER_ENTRY_H
MyNumberEntry.cpp:
#include "MyNumberEntry.h"
ClassImp(MyNumberEntryField);
ClassImp(MyNumberEntry);
/*******************************************
/* class MyNumberEntryField
/*******************************************/
MyNumberEntryField::MyNumberEntryField(const TGWindow * p, Int_t id,
Double_t val, GContext_t norm,
FontStruct_t font, UInt_t option,
ULong_t back)
: TGNumberEntryField(p, id, val, norm, font, option, back) { }
MyNumberEntryField::MyNumberEntryField(const TGWindow * parent,
Int_t id, Double_t val,
EStyle style, EAttribute attr,
ELimit limits, Double_t min,
Double_t max)
: TGNumberEntryField(parent, id, val, style, attr, limits, min, max) { }
MyNumberEntryField::~MyNumberEntryField()
{
}
void MyNumberEntryField::SetNumber(Double_t val)
{
// set the number in the base class
TGNumberEntryField::SetNumber(val);
// then do my stuff
DoMyStuff(); // function not shown
}
/*******************************************
/* class MyNumberEntry
/*******************************************/
MyNumberEntry::MyNumberEntry(const TGWindow *parent, Double_t val,
Int_t digitwidth, Int_t id,
EStyle style,
EAttribute attr,
ELimit limits,
Double_t min, Double_t max)
: TGNumberEntry(parent, val, digitwidth, id, style, attr, limits, min, max)
{
}
MyNumberEntry::~MyNumberEntry()
{
}
ROOT Version: 5.28
Platform: Window 7
Compiler: VS2008