c++visual-studioc++20c++-modules

How to hide implementation details in C++ modules?


I am new to C++ modules. I am using Visual Studio 2022.

Let's say I am creating a DLL, and I don't want my users to see implementation details of my class. How can I achieve this in C++ modules? Mostly I am seeing examples over the Internet, implementing functions in the same file.

Can I safely say, module interfaces are similar to header files & module implementation is similar to cpp file?

Here is my example implementation, is this correct?

AnimalParent.ixx

export module Animal:Parent;

export class Animal
{
public:
    virtual void say();
};

AnimalParent.cpp

module Animal:Parent;

#include <iostream>

void Animal::say()
{
    std::cout << "I am Animal" << std::endl;
}

Animal.cat.ixx

export module Animal:Cat;

import :Parent;

export class Cat :public Animal
{
public:
    void say() override;
};

AnimalCat.cpp

module Animal:Cat;

#include <iostream>

void Cat::say()
{
    std::cout << "I am cat" << std::endl;
}

Animal.ixx

export module Animal;

export import :Parent;
export import :Cat;

Questions:

  1. Is this implementation correct?

  2. Can I safely assume that files contain export module name(.ixx extension) - similar to header files & module name - similar to respective source file?

  3. If I shift this DLL to my customer, what all should I give? My DLL and the folder containing .ixx files?

  4. How will they integrate my DLL? In the current header files system, they will refer to the header files directory in Additional include directories, and link to the lib. Here, do they have to refer to the folder containing .ixx files in Additional include directories & link the lib?


Solution

  • question 1 & 2: Yes.

    question 3.

    To use module in dll, you need to export the symbol using __declspec(dllexport) .

    AnimalParent.ixx

    export module Animal:Parent;
    export class  __declspec(dllexport)   Animal
    {
    public:
        virtual void say();
    };
    

    Animal.cat.ixx

    export module Animal:Cat;
    
    import :Parent;
    export class __declspec(dllexport)  Cat :public Animal
    {
    public:
        void say() override;
    };
    

    what all should I give

    1. DLL and Lib files.
    2. ModuleName.ixx.ifc files. These files are generated by Visual Studio after building the DLL, similar to compiled header files. You can find them in the obj folder of your project (vcxproj project folder/x64/debug or release/).

    For your project, there are three files: AnimalParent.ixx.ifc, Animal.cat.ixx.ifc, Animal.ixx.ifc.

    question 4: how to use the module

    1.Link the lib file.

    2.Import ifc files: In project properties-> C/C++ -> Command Line -> Additional options:

    /reference "<path> \AnimalParent.ixx.ifc" 
    /reference "<path> \Animal.cat.ixx.ifc," 
    /reference "<path> \Animal.ixx.ifc" 
    

    Code: C++ 20 standard

    import Animal;
    int main()
    {
        Animal Ani;
        Ani.say();
        Cat cat;
        cat.say();
    }