Здравствуйте, Sheridan, Вы писали:
S>class Exporting
S>{
S>public:
S> virtual int func() = 0;
S> virtual float other() = 0;
S>};
Это поломается при использовании между компиляторами с разным размером и/или представлением int и float или разной конвенцией вызовов по умолчанию. На Windows я бы переписал так:
class Exporting
{
public:
virtual INT __stdcall func() = 0;
virtual DOUBLE __stdcall other() = 0;
};
Поскольку такого же вида определения используются в Windows SDK, компилятор, который не обеспечит совместимость, не сможет компилировать виндовые приложения.
Ну и если в реализующем классе используются какие-нибудь классы (std::string, контейнеры, etc.), в интерфейсе их показывать нельзя. Можно дать доступ к внутренностям (s.c_str(), s.data(), &*s.begin(), &s[0]), с учётом времени жизни соответствующих ссылок и указателей.
S>class My : public Exporting
S>{
S>public:
S> int funct() { return m_str.size(); }
S> float other() { return 4.4; }
S>private:
S> std::string m_str;
S>};
S>extern "C"
S>{
S> Exporting * getClass();
S>}
S>Exporting * getClass()
S>{
S> return new My();
S>}
Здесь ещё нужен механизм удаления. Либо extern "C" void deleteObject(Exporting *), либо метод в интерфейсе. Идиоматично будет сразу навернуть в интерфейсе интрузивный подсчёт ссылок через AddRef() / Release() и выполнять delete this из Release(), когда счётчик ссылок падает до нуля.
С клиентской стороны можно добавить умный указатель, инкапсулирующий вызовы AddRef/Release (в случае подсчёта ссылок) или Clone/deleteObject (в случае обычного владения).