Problemas com Plugins C++ no Linux
Estou trabalhando em um sistema de plugin para substituir bibliotecas compartilhadas.
Estou ciente dos problemas da ABI ao projetar uma API para libs compartilhados e pontos de entrada nas libs, tais como classes exportadas, deve ser cuidadosamente projetada.
Por exemplo, Adicionar, Remover ou reordenar variáveis de membro privado de uma classe exportada pode levar a diferentes layout de memória e erros de tempo de execução (do meu entendimento, é por isso que o padrão Pimpl pode ser útil). Claro que há muitas outras armadilhas a evitar ao modificar classes exportadas.
Construí aqui um pequeno exemplo para ilustrar a minha pergunta.
Primeiro, eu forneço o seguinte cabeçalho para o desenvolvedor de plugins :
// character.h
#ifndef CHARACTER_H
#define CHARACTER_H
#include <iostream>
class Character
{
public:
virtual std::string name() = 0;
virtual ~Character() = 0;
};
inline Character::~Character() {}
#endif
Em seguida, o plugin é construído como uma lib compartilhada " libcharacter.so
" :
#include "character.h"
#include <iostream>
class Wizard : public Character
{
public:
virtual std::string name() {
return "wizard";
}
};
extern "C"
{
Wizard *createCharacter()
{
return new Wizard;
}
}
E, finalmente, a aplicação principal que usa o plugin :
#include "character.h"
#include <iostream>
#include <dlfcn.h>
int main(int argc, char *argv[])
{
(void)argc, (void)argv;
using namespace std;
Character *(*creator)();
void *handle = dlopen("../character/libcharacter.so", RTLD_NOW);
if (handle == nullptr) {
cerr << dlerror() << endl;
exit(1);
}
void *f = dlsym(handle, "createCharacter");
creator = (Character *(*)())f;
Character *character = creator();
cout << character->name() << endl;
dlclose(handle);
return 0;
}
É suficiente definir uma classe abstrata para se livrar de todas as questões ABI?