Hi Everyone
I’m pretty new to Root so it is very well possible that I am asking a trivial/dumb question. However, I could not find a solution by myself for the following problem, even after extensive googling and going through the Root documentation, so I hope I will find a solution here - I’m already very thankful for your help!
First off some Specs:
OS: Ubuntu 16.04
IDE: Codeblocks 16.01
Compiler: GNU GCC 5.4.0
Root Version: 6.10/00 (compiled from the sources)
General Description of the Problem:
I built a C++ project from the Scratch in Codeblocks, added the include paths, added the library paths, linked the Libraries.
I want to build a very simple GUI, using the root framework, that basically draws a chart once a textbutton is clicked.
For this, I build a new class “ui”, that contains all the GUI variables, a constructor and a function “push1” that draws the chart to the respective canvas.
Before Compiling, I run rootcling with the header in which the ui class is defined and the guiLinkDef.hh file containing the link definition, in order to generate a file “Dictoutput.cxx”, which is then also included into the codeblocks project.
If I put the definition of the function “push1” into the class “ui” (in the headerfile), everything works as it should.
However, once i only declare the function “push1” in the gui.hh header file, but put the definition in the gui.cpp file, I get the following error message:
IncrementalExecutor::executeFunction: symbol '_ZN2ui5push1Ev' unresolved while linking symbol '__cf_3'!
You are probably missing the definition of ui::push1()
Maybe you need to load the corresponding shared library?
Error in <TClingCallFunc::make_wrapper>: Failed to compile
==== SOURCE BEGIN ====
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security"
__attribute__((used)) extern "C" void __cf_3(void* obj, int nargs, void** args, void* ret)
{
((ui*)obj)->push1();
return;
}
#pragma clang diagnostic pop
==== SOURCE END ====
Error in <TClingCallFunc::Exec(address, interpVal)>: Called with no wrapper, not implemented!
What is the mistake I am making?
Here all the source codes of the project:
main.cpp
#include "TApplication.h"
#include "gui.hh"
int main()
{
TApplication app{"test",0,0 };
auto ui1 = new ui();
app.Run();
return 0;
}
gui.hh
// Mainframe macro generated from application: C:\root_v5.34.36\bin\root.exe
// By ROOT version 5.34/36 on 2017-03-18 13:17:26
#ifndef ROOT_TGDockableFrame
#include "TGDockableFrame.h"
#endif
#ifndef ROOT_TGMenu
#include "TGMenu.h"
#endif
#ifndef ROOT_TGMdiDecorFrame
#include "TGMdiDecorFrame.h"
#endif
#ifndef ROOT_TG3DLine
#include "TG3DLine.h"
#endif
#ifndef ROOT_TGMdiFrame
#include "TGMdiFrame.h"
#endif
#ifndef ROOT_TGMdiMainFrame
#include "TGMdiMainFrame.h"
#endif
#ifndef ROOT_TGMdiMenu
#include "TGMdiMenu.h"
#endif
#ifndef ROOT_TGListBox
#include "TGListBox.h"
#endif
#ifndef ROOT_TGNumberEntry
#include "TGNumberEntry.h"
#endif
#ifndef ROOT_TGScrollBar
#include "TGScrollBar.h"
#endif
#ifndef ROOT_TGComboBox
#include "TGComboBox.h"
#endif
#ifndef ROOT_TGuiBldHintsEditor
#include "TGuiBldHintsEditor.h"
#endif
#ifndef ROOT_TRootBrowser
#include "TRootBrowser.h"
#endif
#ifndef ROOT_TGuiBldNameFrame
#include "TGuiBldNameFrame.h"
#endif
#ifndef ROOT_TGFrame
#include "TGFrame.h"
#endif
#ifndef ROOT_TGFileDialog
#include "TGFileDialog.h"
#endif
#ifndef ROOT_TGShutter
#include "TGShutter.h"
#endif
#ifndef ROOT_TGButtonGroup
#include "TGButtonGroup.h"
#endif
#ifndef ROOT_TGCommandPlugin
#include "TGCommandPlugin.h"
#endif
#ifndef ROOT_TGCanvas
#include "TGCanvas.h"
#endif
#ifndef ROOT_TGFSContainer
#include "TGFSContainer.h"
#endif
#ifndef ROOT_TGuiBldEditor
#include "TGuiBldEditor.h"
#endif
#ifndef ROOT_TGColorSelect
#include "TGColorSelect.h"
#endif
#ifndef ROOT_TGTextEdit
#include "TGTextEdit.h"
#endif
#ifndef ROOT_TGButton
#include "TGButton.h"
#endif
#ifndef ROOT_TGFSComboBox
#include "TGFSComboBox.h"
#endif
#ifndef ROOT_TGLabel
#include "TGLabel.h"
#endif
#ifndef ROOT_TGView
#include "TGView.h"
#endif
#ifndef ROOT_TGMsgBox
#include "TGMsgBox.h"
#endif
#ifndef ROOT_TRootGuiBuilder
#include "TRootGuiBuilder.h"
#endif
#ifndef ROOT_TGFileBrowser
#include "TGFileBrowser.h"
#endif
#ifndef ROOT_TGTab
#include "TGTab.h"
#endif
#ifndef ROOT_TGListView
#include "TGListView.h"
#endif
#ifndef ROOT_TGSplitter
#include "TGSplitter.h"
#endif
#ifndef ROOT_TGTextEntry
#include "TGTextEntry.h"
#endif
#ifndef ROOT_TGStatusBar
#include "TGStatusBar.h"
#endif
#ifndef ROOT_TGToolBar
#include "TGToolBar.h"
#endif
#ifndef ROOT_TGuiBldDragManager
#include "TGuiBldDragManager.h"
#endif
#ifndef ROOT_TGObject
#include "TGObject.h"
#endif
#include "Riostream.h"
#include "RQ_OBJECT.h"
#include "TCanvas.h"
#include "TRootEmbeddedCanvas.h"
#include "TF1.h"
#include "TObject.h"
#include "TApplication.h"
class ui{
RQ_OBJECT("ui")
public:
ui();
void push1();
TGMainFrame *fMainFrame1654;
TGVerticalFrame *fVerticalFrame1325;
TGHorizontalFrame *fHorizontalFrame1330 ;
TGTextButton *fTextButton1353;
TRootEmbeddedCanvas *fRootEmbeddedCanvas1337;
};
#include "gui.hh"
ui::ui(){
// main frame
fMainFrame1654 = new TGMainFrame(gClient->GetRoot(),10,10,kMainFrame | kVerticalFrame);
fMainFrame1654->SetName("fMainFrame1654");
// vertical frame
fVerticalFrame1325 = new TGVerticalFrame(fMainFrame1654,577,559,kVerticalFrame);
fVerticalFrame1325->SetName("fVerticalFrame1325");
// horizontal frame
fHorizontalFrame1330 = new TGHorizontalFrame(fVerticalFrame1325,573,26,kHorizontalFrame);
fHorizontalFrame1330->SetName("fHorizontalFrame1330");
fTextButton1353 = new TGTextButton(fHorizontalFrame1330,"fTextButton1353",-1,TGTextButton::GetDefaultGC()(),TGTextButton::GetDefaultFontStruct(),kRaisedFrame);
fTextButton1353->SetTextJustify(36);
fTextButton1353->SetMargins(0,0,0,0);
fTextButton1353->SetWrapLength(-1);
fTextButton1353->Resize(96,22);
fHorizontalFrame1330->AddFrame(fTextButton1353, new TGLayoutHints(kLHintsLeft | kLHintsTop,2,2,2,2));
fVerticalFrame1325->AddFrame(fHorizontalFrame1330, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
// embedded canvas
fRootEmbeddedCanvas1337 = new TRootEmbeddedCanvas(0,fVerticalFrame1325,573,525,kSunkenFrame);
fRootEmbeddedCanvas1337->SetName("fRootEmbeddedCanvas1337");
Int_t wfRootEmbeddedCanvas1337 = fRootEmbeddedCanvas1337->GetCanvasWindowId();
TCanvas *c123 = new TCanvas("c123", 10, 10, wfRootEmbeddedCanvas1337);
fRootEmbeddedCanvas1337->AdoptCanvas(c123);
fVerticalFrame1325->AddFrame(fRootEmbeddedCanvas1337, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY,2,2,2,2));
fMainFrame1654->AddFrame(fVerticalFrame1325, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,1,1,1,1));
fMainFrame1654->SetMWMHints(kMWMDecorAll,
kMWMFuncAll,
kMWMInputModeless);
fMainFrame1654->MapSubwindows();
fMainFrame1654->Resize(fMainFrame1654->GetDefaultSize());
fMainFrame1654->MapWindow();
fMainFrame1654->Resize(579,561);
fTextButton1353->Connect("Clicked()", "ui",this,"push1()");
}
void ui::push1(){
TF1 *fa1 = new TF1("fa1","sin(2*x)/x",0,10);
fRootEmbeddedCanvas1337->GetCanvas()->cd();
fa1->Draw();
fRootEmbeddedCanvas1337->GetCanvas()->Update();
}
guiLinkDef.hh:
#ifndef guiLinkDef_h__
#define guiLinkDef_h__
#ifdef __CLING__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class ui;
#pragma link C++ function ui::push1;
#endif
#endif // guiLinkDef_h__
The command I use to build the Dictionary:
rootcling -f DictOutput.cxx -c -p gui.hh guiLinkDef.hh
The dictionary file DictOutput.cxx that is generated by the above command:
// Do NOT change. Changes will be lost next time file is generated
#define R__DICTIONARY_FILENAME DictOutput
/*******************************************************************/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define G__DICTIONARY
#include "RConfig.h"
#include "TClass.h"
#include "TDictAttributeMap.h"
#include "TInterpreter.h"
#include "TROOT.h"
#include "TBuffer.h"
#include "TMemberInspector.h"
#include "TInterpreter.h"
#include "TVirtualMutex.h"
#include "TError.h"
#ifndef G__ROOT
#define G__ROOT
#endif
#include "RtypesImp.h"
#include "TIsAProxy.h"
#include "TFileMergeInfo.h"
#include <algorithm>
#include "TCollectionProxyInfo.h"
/*******************************************************************/
#include "TDataMember.h"
// Since CINT ignores the std namespace, we need to do so in this file.
namespace std {} using namespace std;
// Header files passed as explicit arguments
#include "gui.hh"
// Header files passed via #pragma extra_include
namespace ROOT {
static TClass *ui_Dictionary();
static void ui_TClassManip(TClass*);
static void delete_ui(void *p);
static void deleteArray_ui(void *p);
static void destruct_ui(void *p);
// Function generating the singleton type initializer
static TGenericClassInfo *GenerateInitInstanceLocal(const ::ui*)
{
::ui *ptr = 0;
static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(::ui));
static ::ROOT::TGenericClassInfo
instance("ui", "gui.hh", 132,
typeid(::ui), ::ROOT::Internal::DefineBehavior(ptr, ptr),
&ui_Dictionary, isa_proxy, 0,
sizeof(::ui) );
instance.SetDelete(&delete_ui);
instance.SetDeleteArray(&deleteArray_ui);
instance.SetDestructor(&destruct_ui);
return &instance;
}
TGenericClassInfo *GenerateInitInstance(const ::ui*)
{
return GenerateInitInstanceLocal((::ui*)0);
}
// Static variable to force the class initialization
static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstanceLocal((const ::ui*)0x0); R__UseDummy(_R__UNIQUE_DICT_(Init));
// Dictionary for non-ClassDef classes
static TClass *ui_Dictionary() {
TClass* theClass =::ROOT::GenerateInitInstanceLocal((const ::ui*)0x0)->GetClass();
ui_TClassManip(theClass);
return theClass;
}
static void ui_TClassManip(TClass* ){
}
} // end of namespace ROOT
namespace ROOT {
// Wrapper around operator delete
static void delete_ui(void *p) {
delete ((::ui*)p);
}
static void deleteArray_ui(void *p) {
delete [] ((::ui*)p);
}
static void destruct_ui(void *p) {
typedef ::ui current_t;
((current_t*)p)->~current_t();
}
} // end of namespace ROOT for class ::ui
namespace {
void TriggerDictionaryInitialization_DictOutput_Impl() {
static const char* headers[] = {
"gui.hh",
0
};
static const char* includePaths[] = {
"/home/andreas/Software/Root/include",
"/home/andreas/FINAL/",
0
};
static const char* fwdDeclCode = R"DICTFWDDCLS(
#line 1 "DictOutput dictionary forward declarations' payload"
#pragma clang diagnostic ignored "-Wkeyword-compat"
#pragma clang diagnostic ignored "-Wignored-attributes"
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
extern int __Cling_Autoloading_Map;
class __attribute__((annotate("$clingAutoload$gui.hh"))) ui;
)DICTFWDDCLS";
static const char* payloadCode = R"DICTPAYLOAD(
#line 1 "DictOutput dictionary payload"
#ifndef G__VECTOR_HAS_CLASS_ITERATOR
#define G__VECTOR_HAS_CLASS_ITERATOR 1
#endif
#define _BACKWARD_BACKWARD_WARNING_H
#include "gui.hh"
#undef _BACKWARD_BACKWARD_WARNING_H
)DICTPAYLOAD";
static const char* classesHeaders[]={
"ui", payloadCode, "@",
nullptr};
static bool isInitialized = false;
if (!isInitialized) {
TROOT::RegisterModule("DictOutput",
headers, includePaths, payloadCode, fwdDeclCode,
TriggerDictionaryInitialization_DictOutput_Impl, {}, classesHeaders);
isInitialized = true;
}
}
static struct DictInit {
DictInit() {
TriggerDictionaryInitialization_DictOutput_Impl();
}
} __TheDictionaryInitializer;
}
void TriggerDictionaryInitialization_DictOutput() {
TriggerDictionaryInitialization_DictOutput_Impl();
}