34 votes

l'assouplissement c++, objective-c/cocoa combler par la métaprogrammation?

Dans un pur C++ monde, nous pouvons générer de l'interfaçage ou de la colle de code entre les différents composants des interfaces ou au moment de la compilation, à l'aide d'une combinaison du modèle de base au moment de la compilation et à l'exécution des techniques (par exemple la plupart automatiquement marshall/à partir d'appels à l'aide de l'héritage types).

Lorsque l'interface C++ d'applications avec Objective-C/Cocoa pour l'interface graphique, l'intégration du système ou de l'IPC cependant, les choses deviennent plus difficiles, en raison de la moins de typage strict - mais souvent pas plus d'une télévision repitive la couche d'interface est nécessaire: mince combler les délégués ont défini ou conversion de code pour le langage de transition des appels doit être écrit.

Si vous avez à traiter avec des interfaces de non-trivial de taille et que vous voulez éviter basée sur un script de génération de code, cela devient vite lourd et est juste une douleur à chaque fois refactorings avoir lieu. En utilisant une combinaison de (modèle) métaprogrammation et l'Objective-C runtime library, il devrait être possible de réduire la quantité de code considérablement...

Avant d'aller me réinventer la roue (et éventuellement de perdre du temps), personne ne sait sur les techniques, les meilleures pratiques et les exemples dans ce sens?


Comme pour l'exemple, disons que nous avons besoin d'un délégué qui prend en charge ce protocole:

- (NSString*)concatString:(NSString*)s1 withString:(NSString*)s2;
- (NSNumber*)     indexOf:(CustomClass*)obj;

Au lieu de mettre en place un Obj-C classe désormais explicitement que les ponts de C++-exemple, j'aimerais faire quelque chose comme ceci à la place:

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;
    }
};

Tout ce qui devrait être besoin de l'utilisateur à soutenir d'autres types serait de se spécialiser une conversion d'un modèle de fonction:

template<class To, class From> To convert(const From&);

template<> 
NSString* convert<NSString*, std::string>(const std::string& s) { 
    // ...
}

// ...

L'exemple ci-dessus n'est évidemment ignorer le support pour les protocoles officiels etc. mais doit obtenir le point à travers. En outre, les informations de type pour Objc-runtime-types étant la plupart du temps pourri dans certains indigènes-les types de classe ou de type , je ne pense pas que la spécification explicite de paramètre et les types de retour pour les délégué-méthodes peuvent être évités.

5voto

Georg Fritzsche Points 59185

Je n'ai rien trouvé de satisfaisant et est venu avec un prototype qui, compte tenu de la suite de protocole informel:

- (NSString*)concatString:(NSString*)s1 withString:(NSString*)s2;

et ce code 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;
}

permet de créer et de passage d'un délégué:

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()];

qui peut ensuite être utilisé:

NSString* result = [delegate concatString:@"abc" withString:@"def"];
assert([result compare:@"abcdef"] == NSOrderedSame);

Coup de pouce.La fonction des objets peut également être transmis, ce qui signifie coup de pouce.Lier peut facilement être utilisé aussi bien.

Alors que l'idée de base fonctionne, c'est encore un prototype. J'ai fait un court billet de blog sur le sujet et le prototype de source est disponible via bitbucket. Des commentaires constructifs et des idées de bienvenue.

4voto

Kerido Points 1950

Avez-vous regardé la bibliothèque wxWidgets? Je n'ai pas de code en Objective-C, mais au moins les développeurs affirment bon support pour Cocoa/Objective-C. ce Qui signifie, qu'ils ont une certaine cartographie à partir de C++ en œuvre en quelque sorte. Le site web de la bibliothèque est http://www.wxwidgets.org.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X