1

I'm trying to create a library which exposes one class to the outside with a pimpl idiom. This implementation works, meaning I can add functionality to the "idcomimpl" class without breaking ABI. But how do I add the data structure in this whole design that is provided by the application and required by this library. What I want to know is, is it even possible to implement it such that the data structure is exposed to the outside (application) but I can still add member variables to the structure without breaking the ABI. Currently the only header that has to be included by the application is idcom.h. Should I use the same pimpl approach for the data structs as I did for the idcom class?

idcom_global.h :

#if defined( IDCOM_LIBRARY )
 #define IDCOMDLL_API  __declspec( dllexport )
#else
 #define IDCOMDLL_API  __declspec( dllimport )
#endif

idcom.h :

class idcomImpl;

class  idcom
{
public:
    IDCOMDLL_API idcom();
    IDCOMDLL_API ~idcom(){};

    virtual void doSomething();

private:
    std::unique_ptr< idcomImpl > m_impl;
};

idcom.cpp :

idcom::idcom() :
    m_impl( new idcomImpl())
{}

void idcom::doSomething()
{
   m_impl->doSomething();
}

idcomimpl.h :

class idcomImpl
{
public:
    idcomImpl(){};
    ~idcomImpl(){};

    virtual void doSomething(); 
};

idcomimpl.cpp :

void doSomething()
{
....//implementation here
}

idcom_connection.h ======> the data structure how to incorporate in design ???

struct IDCOMDLL_API idcomConnection
{
    std::string id;
    std::string name;
    std::string type;

    //expansion of members here in the future e.g. std::string fullServerName;
};
xyfix
  • 61
  • 1
  • 7
  • ***What I want to know is, is it even possible to implement it such that the data structure is exposed to the outside (application) but I can still add member variables to the structure without breaking the ABI.*** I am pretty sure you can't expose the structure to the outside. You need to hide the details from the code that will call this and provide a member function to query what is in the structure and other functions to read and change the values of a variable in the structure. – drescherjm Feb 26 '20 at 13:00
  • Ok,I should not expose the structure to the outside so I need some kind of a pointer implementation. The application that will call the code will only see a pointer to the data structure ?? can you please add a code snippet related to my code example to elaborate your comment ? – xyfix Feb 26 '20 at 13:27
  • You can use PIMPL and a few access functions. No pointers are needed other than the one smart pointer for PIMPL. Think of std::map where the key is the name of the variable and the value is its value. – drescherjm Feb 26 '20 at 13:29
  • As @drescherjm mentioned, exposing the structure is a no-no when following PIMPL. The Qt framework heavily uses pimpl and has a [short (easy to read) article](https://wiki.qt.io/D-Pointer) that explains why adding a member to the struct would mess up with the offset and crash applications that were working fine with older versions of your lib. – diogoslima Feb 26 '20 at 13:37
  • The Qt property system could be related to what I described in my previous post. [https://doc.qt.io/qt-5/properties.html](https://doc.qt.io/qt-5/properties.html) in the case I was talking about you would use the "Reading and Writing Properties with the Meta-Object System" technique not the getter and setter functions those would be in the PIMPL if they exist at all. – drescherjm Feb 26 '20 at 13:47
  • I read those articles ( not sure if I got everything ) but how would I apply this "property" principle in my C++ without using Qt? do I need to create a meta-object system? ( which will be finished in 2021 :-) ) . So how do other c++ library vendors do this? – xyfix Feb 26 '20 at 22:29

0 Answers0