Общая стратегия перевода Objective-to-C ++

0

Я хотел бы разоблачить обработчики уведомлений ObjC для моего кода клиента C++. Я делаю это так.

  1. Я обернул объект ObjC (назовите его X) внутри объекта C++.
  2. X наблюдает за уведомлением и регистрирует обратный вызов (назовите его F).
  3. F преобразует структуры ObjC из уведомления в свои C++ аналоги, вызывает зарегистрированную пользователем глобальную функцию C++ обратного вызова (назовите ее FF). Переведенные C++ структуры становятся входными аргументами FF.

Теперь проблема в том, что исходные структуры ObjC аргументов являются сложными, содержащими несколько слоев объектов ObjC, которые необходимо перевести.

На моей стороне оберточный наблюдатель F не должен делать ничего особенного, просто называя клиентский FF.

Какова более правильная стратегия моего перевода на данный момент?

Нужно ли мне:

  1. Переведите эти структуры на нижний уровень всех их членов, чтобы я имел эквивалентные структуры C++ для использования в качестве аргументов или,
  2. Создайте класс C++, чтобы обернуть эти аргументы в один объект и открыть интерфейс класса для пользователя, чтобы они могли использовать эти C++ -обловленные аргументы в своей реализации C++ или,
  3. Откажитесь от идеи об упаковке и попросите пользователя ввести код в ObjC и зарегистрировать собственные функции наблюдателя напрямую?

Мои целевые пользователи - разработчики iOS, которые могут или не могут быть разработчиками Android.

Теги:

1 ответ

1

Вы можете смешать c++ и объект c++ в файле реализации.mm. Это означает, что вы можете присвоить c++ лямбда (или блок) объекту c++, который ссылается на владельца c++.

что-то вроде этого:

implementation.mm:

@interface Shim : NSObject
{
  std::function<void>() _notify;
}
@end

@implementation Shim
- void register_cpp(std::function<void>() f)
{
  _notify = std::move(f);
}

- (void) my_handler()
{
  if(_notify)
    _notify();
}
@end

struct cpp_class::impl {
  impl()
  : _shim([Shim alloc[init]])
  {
    _shim.register_cpp(std::bind(&impl::callback, this));
  }

private:
  void callback() {
    // do callback here;
  }
  Shim* _shim;
};

cpp_class::cpp_class()
: _impl(new impl)
{
}

cpp_class::~cpp_class()
{
  delete _impl;
}

header.h:

struct cpp_class{
  cpp_class();
  ~cpp_class();

private:
  struct impl;
  impl* _impl;
};

На самом деле вам нужно быть осторожным, чтобы объекты все еще существовали при выполнении обратных вызовов (аргументы в пользу weak_ptr :: lock(), enable_shared_from_this и т.д.), Поскольку object-c любит помещать обратные вызовы в цикл выполнения потока (в основном очередь), и это означает, что ваш объект c++ может уйти до того, как поступит обратный вызов, но этот код должен дать вам правильную идею.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню