Wygląda na to, że potrzebujesz interfejsów i implementacji interfejsów w bibliotece.
Nie ma jednego konkretnego sposobu na zrobienie tego. Zwłaszcza kiedy mowa o kompatybilności wstecznej.
Często implementuje się to używając metod wirtualnych.
Drzewo plików:
Public/Core.h
Private/CoreImpl.h
Private/Point.h
Private/Triangle.h
Private/CoreImpl.cpp
To co jest w Public/ jest dla użytkownika końcowego biblioteki. To co jest w Private/ jest implementacją biblioteki.
Często stosowaną konwencją są określenia include
(odpowiednik Public
), i src
(odpowiednik Private
).
// Public/Core.h
#pragma once
class Core
{
public:
virtual void SomeMethod() = 0;
};
Core *CreateCore();
void DestroyCore( Core *core );
// Private/Point.h
#pragma once
class Point
{
};
// Private/Triangle.h
#pragma once
class Triangle
{
};
// Private/CoreImpl.h
#include "Point.h"
#include "Triangle.h"
class CoreImpl : public Core
{
public:
virtual void SomeMethod() override;
private:
Point m_point;
Triangle m_triangle;
};
// Private/CoreImpl.cpp
#include "CoreImpl.h"
void CoreImpl::SomeMethod()
{
// Implementacja funkcji Core::SomeMethod()
}
Core *CreateCore()
{
return new CoreImpl;
}
void DestroyCore( Core *core )
{
delete static_cast< CoreImpl * >( core ); // Jeśli nie chcesz tutaj static_cast'a, to destruktor Core musi być wirtualny
}
Z punktu widzenia użytkownika:
#include "Core.h"
int main()
{
Core *core = CreateCore();
core->SomeMethod();
DestroyCore( core );
}
Użytkownik dostaje tylko zawartość Public/ i .lib, nie zna zawartości Private/.
Można też to robić inaczej, gdzie kod C++ jest wrapperem tylko na kod C. Polecam zajrzeć do tego jak jest zrobiony Discord SDK (https://discord.com/developers/docs/game-sdk/sdk-starter-guide ) (download: https://dl-game-sdk.discordapp.net/2.5.6/discord_game_sdk.zip)