Classes nested in namespace

Hello,

I have the following issue,
I simple case.
I have declared a class

#pragma once

#ifndef EsbIO_hpp
#define EsbIO_hpp 1

#include <string>
//#include "G4VPhysicalVolume.hh"
#include "TObject.h"

namespace core {
namespace esbcore {

class EsbIO : public TObject
{
public:
    EsbIO();
    ~EsbIO();

    int ExportTGeoVolume(std::string path_to_file);
private:
    ClassDef(EsbIO,6);
};

}
}
#endif

and its implementation file as:

#include "core/io/EsbIO.hpp"
#include "TGeoManager.h"


namespace core {
namespace esbcore{

EsbIO::EsbIO()
{
}

EsbIO::~EsbIO()
{
}

int EsbIO::ExportTGeoVolume(std::string path_to_file){
    return gGeoManager->Export(path_to_file.c_str());
}

}
}

The linkdef.h is
#ifdef CINT

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ nestedclass;
#pragma link C++ nestedtypedef;

#pragma link C++ namespace core+;
#pragma link C++ namespace core::esbcore+;

#pragma link C++ class core::esbcore::EsbIO+;

#endif

building with the root macro

ROOT_GENERATE_DICTIONARY( G___esbio ${CMAKE_CURRENT_SOURCE_DIR}/io/EsbIO.hpp 
                            LINKDEF ${CMAKE_CURRENT_SOURCE_DIR}/EsbioLinkDef.h
                            MODULE esbio} )

It generates the pcm, rootmap file etc.
But when I execute it from a .C file as

..
std::string path = "<some_path>/test_core.gdml";
core::esbcore::EsbIO* tt = new core::esbcore::EsbIO()
...

I get the following error:

In file included from input_line_8:1:
/home/framework/build/core/test.C:20:5: error: use of undeclared identifier 'core'
    core::esbcore::EsbIO* tt = new core::esbcore::EsbIO();
    ^
/home/framework/build/core/test.C:20:36: error: use of undeclared identifier 'core'
    core::esbcore::EsbIO* tt = new core::esbcore::EsbIO();

What mistake have I made in the linkdef file or somewhere else?

_ROOT Version: Build from source → tags/v6-28-04
_Platform: Linux mint 21.2
_Compiler: g++ (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0

Removing the namespace , the .C works.
I found several discussions on the issue (some quite old, but I guess relevant)

And from one answer I found that if the lib contains a class without a namespace , loading the class will load the library. But since namespaces can span multiple libraries, that is why they don’t cause automatic loading of the library and thus the above error.
Anyone having other information?

Issue was that the root_generate_dictionary macro creates a file .pcm in the . This pcm, once created upon first usage of the EsbIO, is not updated. Unloading the module also does not remove the pcm file. Thus the initial EsbIO class was not within a namespace, subsequently adding a namespace regardless of the linkdef.h file, it will give strange errors- from. Undefined members to linkage errors.
The solution was to add in the build script for cmake to remove the pcm file.

1 Like

Thanks @georgi_petkov for memorialising this process in a post: hopefully it will be useful for other users in the future!