CINT fails to link shared library


_ROOT Version: 6.14
_Platform: CentOS
_Compiler: g++


Dear experts,
I am having trouble linking a C++ class using CINT. When I load the library in a python script using gSystem.Load("libTestClass.so") and try to use the class method I get an error

IncrementalExecutor::executeFunction: symbol '_ZN9TestClass15giveMeTheAnswerEv' unresolved while linking symbol '__cf_14'!
You are probably missing the definition of TestClass::giveMeTheAnswer()
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_14(void* obj, int nargs, void** args, void* ret)
{
   if (ret) {
      new (ret) (TString) (((TestClass*)obj)->giveMeTheAnswer());
      return;
   }
   else {
      ((TestClass*)obj)->giveMeTheAnswer();
      return;
   }
}
#pragma clang diagnostic pop
  ==== SOURCE END ====

 *** Break *** segmentation violation

Which to me looks a problem with the linker. I have Inspected the library.so file using nm, but the class methods seem to be missing from the binary…
Here is the Header file TestClass.h:

#ifndef TESTCLASS_H
#define TESTCLASS_H

#include <iostream>

#include "TString.h"

class TestClass {
public:
	TestClass() { }
	TString giveMeTheAnswer();
	virtual inline ~TestClass() { }

	ClassDef(TestClass,1)
};

#endif

This is TestClass.cpp

#include "Riostream.h"

#include "TestClass.h"

TString TestClass::giveMeTheAnswer()
{
	return "42";
}

TestClass_LinkDef.h

#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ nestedclasses;

#pragma link C++ defined_in "TestClass.h";

#endif

and the Makefile

CC=g++

# common use flags and libraries
CXXFLAGS := -Wall -Wextra  -Woverloaded-virtual -fPIC -W -pipe -ftree-vectorize -Ofast
ROOTLIBS  :=  $(shell root-config --libs) -lRooFit -lRooStats -lTreePlayer
ROOTFLAGS :=  $(shell root-config --cflags)

CXXFLAGS  += $(ROOTFLAGS)
CXXFLAGS  += $(ROOTLIBS)

LDFLAGS       = -O2 # -Wl
SOFLAGS       = -shared
SHLIB    := libTestClass.so
HDRS     := $(wildcard *.h)
COMPILE = $(CC) $(CXXFLAGS) -c

OBJFILES := $(patsubst %.cxx,%.o,$(wildcard *.cxx))
OBJFILES += testclass_dict.o

%.o: %.cxx
	$(CC) $(CXXFLAGS) $(DEBUG) -c $< -o $@

$(SHLIB): $(OBJFILES) $(INTS) $(HDRS)
	  /bin/rm -f $(SHLIB)
	  $(CC) $(SOFLAGS) $(LDFLAGS) $(OBJFILES) -o $(SHLIB)

testclass_dict.o:  $(HDRS)
	rootcint -f testclass_dict.cc -c $(HDRS)
	$(COMPILE) testclass_dict.cc -I. -o testclass_dict.o

clean:
	rm -f *.pcm *.cc *o *.so

What am I doing wrong? Thank you in advance!

Try to rename “TestClass.cpp” into “TestClass.cxx”.

1 Like

Yes, that worked. Thank you very much! Now when I look at the Makefile it seems obvious

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.