В чистом мире C++ мы можем генерировать взаимодействие через интерфейс или склеить код между различными компонентами или интерфейсами во время компиляции, с помощью комбинации основанного на шаблоне времени компиляции и методов во время выполнения (к, например, главным образом автоматически Маршалл к/от вызовам с помощью типов прежней версии).
Имея необходимость соединить интерфейсом с приложениями C++ с Objective-C/Cocoa для GUI, системной интеграции или IPC, хотя, вещи становятся тяжелее из-за менее строгого ввода - все же часто не больше затем, плоский слой интерфейса repitive необходим: худые делегаты образования моста должны быть определены, или код преобразования к вызовам образования моста языка должен быть записан.
Если необходимо иметь дело с интерфейсами нетривиального размера и хотеть избежать основанной на сценарии генерации кода, это быстро становится громоздким и является просто болью каждый раз, когда рефакторинги должны произойти. Используя комбинацию (шаблона) метапрограммирование и библиотека времени выполнения Objective C, должно быть возможно уменьшить объем кода значительно...
Прежде чем я пойду для изобретения велосипед (и возможно напрасно тратить время), кто-либо знает о методах, лучших практиках или примерах в том направлении?
Что касается примера, позволяет, говорят, что нам нужен делегат, который поддерживает этот неофициальный протокол:
- (NSString*)concatString:(NSString*)s1 withString:(NSString*)s2;
- (NSNumber*) indexOf:(CustomClass*)obj;
Вместо того, чтобы реализовать класс Obj-C теперь, когда явно образует мост к C ++-instance, я хотел бы сделать что-то вроде этого вместо этого:
class CppObj {
ObjcDelegate m_del;
public:
CppObj() : m_del(this)
{
m_del.addHandler
<NSString* (NSString*, NSString*)>
("concatString", &CppObj::concat);
m_del.addHandler
<NSNumber* (CustomClass*)>
("indexOf", &CppObj::indexOf);
}
std::string concat(const std::string& s1, const std::string& s2) {
return s1.append(s2);
}
size_t indexOf(const ConvertedCustomClass& obj) {
return 42;
}
};
Все, что должно быть необходимо от пользователя для поддержки дополнительных типов, должно было бы специализировать шаблонную функцию преобразования:
template<class To, class From> To convert(const From&);
template<>
NSString* convert<NSString*, std::string>(const std::string& s) {
// ...
}
// ...
Пример выше, конечно, игнорирует поддержку формальных протоколов и т.д., но должен понять через. Кроме того, из-за информации типа для Objc-типов-выполнения, главным образом затухших в some-native-types или тип класса, я не думаю явная спецификация параметра и возвращаюсь, типов для методов делегата можно избежать.
Я не нашел ничего удовлетворительного и придумал прототип, который, учитывая следующий неофициальный протокол:
- (NSString*)concatString:(NSString*)s1 withString:(NSString*)s2;
и это Код C ++:
struct CppClass {
std::string concatStrings(const std::string& s1, const std::string& s2) const {
return s1+s2;
}
};
std::string concatStrings(const std::string& s1, const std::string& s2) {
return s1+s2;
}
позволяет создавать и передавать делегат:
CppClass cpp;
og::ObjcClass objc("MyGlueClass");
objc.add_handler<NSString* (NSString*, NSString*)>
("concatString:withString:", &cpp, &CppClass::concatStrings);
// or using a free function:
objc.add_handler<NSString* (NSString*, NSString*)>
("concatString:withString:", &concatStrings);
[someInstance setDelegate:objc.get_instance()];
, который затем можно использовать:
NSString* result = [delegate concatString:@"abc" withString:@"def"];
assert([result compare:@"abcdef"] == NSOrderedSame);
объекты Boost.Function также могут быть переданы, что означает, что Boost.Bind может легко также можно использовать.
Хотя основная идея работает, это все еще прототип. Я сделал короткую запись в блоге на эту тему, а исходный текст прототипа доступен через битбакет . Конструктивный вклад и идеи приветствуются.
Вы смотрели на библиотеку wxWidgets? Я не кодирую на Objective-C, но, по крайней мере, разработчики заявляют о достойной поддержке Cocoa/Objective-C. А это значит, что у них как-то реализовано отображение из C++. Сайт библиотеки - http://www.wxwidgets.org.