Советы по абстрактной фабрике, экспорту DLL и умным указателям - PullRequest
2 голосов
/ 19 сентября 2009

Это продолжение одного из моих предыдущих вопросов, и я придумала возможное решение для моего проекта, и мне нужны некоторые советы или рекомендации, если у меня есть это право.

По сути, мой проект - это библиотека, которая будет использоваться и компилироваться как в Linux, так и в Windows, часть Linux не представляет особой проблемы, ее Windows.

Моя библиотека состоит в основном из классов, поэтому 95% кода C ++. Чтобы обеспечить лучшую поддержку и избежать проблем с именами, я собираюсь использовать интерфейсы и фабричные методы для получения экземпляров этих классов, а не вызывать их напрямую. Я также буду использовать extern «C» ТОЛЬКО на заводских функциях, чтобы избежать искажения имени.

Итак, вот вопросы:

  1. Я буду использовать макросы экспорта / импорта в функциях фабрики, но нужно ли мне тогда добавлять экспорт / импорт (__declspec (dllexport / import)) в заголовочные файлы всех классов, которые я хочу предоставить экземпляры для включения интерфейсов базового класса? Или достаточно просто экспортировать заводские функции?

  2. Я также думал об использовании функций умного указателя для автоматического освобождения, хорошая идея или позволить пользователю справиться с этим? Я планировал использовать шаблон autoptr, который является частью стандартной библиотеки и доступен на обеих платформах, верно?

  3. Может ли кто-нибудь осветить, какое соглашение о вызовах мне следует использовать? Я знаю, что она специфична для Microsoft, поэтому я надеюсь, что она не мешает Linux, поэтому я должен оставить это поле пустым и оставить его по умолчанию, как мне кажется, _thiscall или что-то в этом роде.

  4. Я получаю ошибку для этого куска кода, я не уверен, почему, но это связано с внешним "C":

Ошибка:

ошибка: объявление функции C ‘std :: ostream & operator << (std :: ostream &, const MemInfo &) 'конфликтует с | предыдущее объявление ‘std :: ostream & operator << (std :: ostream &, const SpeedInfo &) ’здесь | </p>

ошибка: объявление функции C 'std :: ostream & operator << (std :: ostream &, const analysis_result &)' конфликтует с предыдущим объявлением 'std :: ostream & operator << (std :: ostream &, const MemInfo &)' здесь | </p>

... эти сообщения об ошибках повторяются для всех функций

Вот код:

//WINLIB is my macro for the dllimport/export

extern "C"{

//operator overloading for stream operation
WINLIB std::ostream& operator<<(std::ostream &st, const SpeedInfo &si);
WINLIB std::ostream& operator<<(std::ostream &st, const MemInfo &mi);
WINLIB std::ostream& operator<<(std::ostream &st, const analyzed_result&);
WINLIB std::ostream& operator<<(std::ostream &st, const ustring_set&);
WINLIB std::ostream& operator<<(std::ostream &st, const speed_map&);
WINLIB std::ostream& operator<<(std::ostream &st, const mem_map&);

WINLIB SpeedInfo operator+(SpeedInfo &si, SpeedInfo &si2);
WINLIB SpeedInfo& operator+=(SpeedInfo &si, SpeedInfo &si2);
WINLIB SpeedInfo operator-(SpeedInfo &si, SpeedInfo &si2);
WINLIB SpeedInfo& operator-=(SpeedInfo &si, SpeedInfo &si2);

WINLIB MemInfo operator+(MemInfo &mi, MemInfo &mi2);
WINLIB MemInfo& operator+=(MemInfo &mi, MemInfo &mi2);
WINLIB MemInfo operator-(MemInfo &mi, MemInfo &mi2);
WINLIB MemInfo& operator-=(MemInfo &mi, MemInfo &mi2);
}

Ответы [ 2 ]

1 голос
/ 19 сентября 2009

Я не могу много сказать о вашей заводской идее (это было> 10 лет назад, когда я сделал что-то подобное), но относительно # 4, ваши сообщения об ошибках:

Если вы объявляете что-то как extern "C", это означает, среди прочего, что искажение имени отключено. Но искажение имени - это не просто неприятность, это причина. Перенаправление имен означает, что компилятор будет перетаскивать имена типов аргументов функции в имена функций, чтобы компилятор и компоновщик могли отличать перегруженную функцию друг от друга. Если вы объявите их как extern "C", вы вернетесь на землю C: компилятор не может отличить перегруженные функции друг от друга, и поэтому перегрузка не работает.

1 голос
/ 19 сентября 2009
  1. Достаточно экспортировать фабричную функцию и включить заголовки для классов в коде пользователя.
  2. Если вы не зависите от этого, пусть пользователь выберет свой лучший инструмент для работы.
  3. __ STDCALL
  4. extern "C" дает вам область объявления в стиле c - поэтому вы не можете иметь там перегрузку. см здесь . поскольку win32 dll тоже в стиле c, вы не можете напрямую экспортировать перегруженные функции (подумайте GetProcAddress()).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...