Я рекомендую:
if ([[[UIDevice currentDevice] systemVersion] floatValue] > 3.13) {
; // ...
}
credit: Как настроить таргетинг на определенную версию iPhone?
Самый легкий способ сделать это, по моему скромному мнению, должно иметь простую функцию C, которая возвращает указатель на интерфейс, описанный в другое место. Тогда Ваше приложение, может вызвать все функции того интерфейса, на самом деле не зная, какой класс это использует.
Редактирование: вот простой пример.
В Вашем коде главного приложения, Вы создаете заголовок для интерфейса:
class IModule
{
public:
virtual ~IModule(); // <= important!
virtual void doStuff() = 0;
};
Главное приложение кодируется для использования интерфейса выше без любых деталей о фактической реализации интерфейса.
class ActualModule: public IModule
{
/* implementation */
};
Теперь, модули - DLL имеет фактическую реализацию того интерфейса, и те классы не должны даже быть экспортированы - __declspec (dllexport)
, не необходим. Единственное требование для модулей должно экспортировать единственную функцию, которая создала бы и возвратила бы реализацию интерфейса:
__declspec (dllexport) IModule* CreateModule()
{
// call the constructor of the actual implementation
IModule * module = new ActualModule();
// return the created function
return module;
}
примечание: проверка ошибок не учла - Вы обычно хотели бы проверить, если бы новый возвратил корректный указатель, и необходимо защитить себя от исключений, которые могли бы быть выданы в конструкторе ActualModule
класс.
Затем в Вашем главном приложении, все, в чем Вы нуждаетесь, должно просто загрузить модуль (LoadLibrary
функция) и найти функцию CreateModule
(GetProcAddr
функция). Затем Вы используете класс через интерфейс.
Редактирование 2: Ваш RefCount (базовый класс интерфейса), может быть реализован в (и экспортирован из), главное приложение. Тогда весь Ваш модуль должен был бы связаться с библиотечным файлом главного приложения (да! EXE-файлы могут иметь Библиотечные файлы точно так же, как файлы DLL!) И это должно быть достаточно.
Вы перестраиваете COM. Ваш класс RefCounted является IUnknown. Ваш абстрактный класс является интерфейсом. Сервер COM в DLL имеет entrypoint под названием DllGetClassObject (), это - фабрика классов. Существует много документации, доступной от Microsoft на COM, введите по абсолютному адресу вокруг немного, чтобы видеть, как они сделали это.
[Редактирование: пока я составлял все это, Paulius MaruЕЎka отредактировал его комментарий для высказывания в основном того же. Так извинения за любое дублирование. Хотя я предполагаю, что Вы теперь добрались один для запчасти:)]
Первое, что пришло на ум, и принимающий Visual C++...
необходимо использовать LoadLibrary, чтобы загрузить DLL в динамично, затем использовать GetProcAddress для получения от него адреса функции, которая создаст фактический производный класс, который реализует код DLL. Как Вы решаете сделать, это точно ваше дело (открытие потребности DLLs, способ, которым для представления их функциональности нужно определение, и т.д.) поэтому на данный момент позволяют нам предположить, что плагины только обеспечивают новые реализации Sprite.
, Чтобы сделать это, выберите подпись функции в DLL, который основная программа назовет для создания одного из этих новых спрайтов. Эти подходящие взгляды:
typedef Sprite *(*CreateSpriteFn)();
Затем из основной программы, необходимо будет загрузить DLL (снова, как Вы находите, что этот DLL ваше дело), и получите функцию создания спрайта от него. Я решил, что функция создания спрайта будет вызвана "CreateSprite":
HMODULE hDLL=LoadLibrary(pDLLName);
CreateSpriteFn pfnCreateSprite=CreateSpriteFn(GetProcAddress(hDLL,"CreateSprite"));
Затем для фактического создания одного из них просто вызовите функцию:
Sprite *pSprite=(*pfnCreateSprite)();
, Как только Вы сделаны с DLL и нет никаких объектов, оставленных, которые были созданы им, Вы тогда используете FreeLibrary для избавлений от него:
FreeLibrary(hDLL);
Для создания DLL, который щеголяет этим интерфейсом запишите, что код для производного класса и так далее тогда где-нибудь в коде DLL обеспечивает функцию CreateSprite, в которой программа вызова нужна, с помощью соответствующей подписи:
__declspec(dllexport)
extern "C"
Sprite *CreateSprite()
{
return new MyNewSprite;
}
dllexport вещь означает, что можно использовать GetProcAddress для собирания этой функции по имени, и экстерн "C" удостоверяется, что имя не искажается и не заканчивается как "CreateSprite@4" или что-то как.
Два других примечания:
Возможно, Вы хотите изучить Загрузку Задержки DLL ( http://www.codeproject.com/KB/DLL/Delay_Loading_Dll.aspx ) - это даст Вам, что Вы хотите, не имея необходимость также упорно работать для нее