Je cherche un moyen de faire un NSInvocation
invoquer un IMP
. Par défaut, il invoque le "plus bas" IMP
qu'il peut trouver (c'est-à-dire la version la plus récente), mais je cherche un moyen de lui faire invoquer un IMP
de plus haut dans la chaîne d'héritage. Les IMP
que je veux invoquer est déterminée dynamiquement, sinon je pourrais utiliser la fonction super
ou quelque chose comme ça.
J'ai pensé utiliser le -forwardInvocation:
mécanisme de capture d'un message (facile et qui fonctionne déjà) et de modifier ensuite le message. IMP
Il est donc renvoyé à une méthode qui n'est ni la méthode super
ni l'implémentation du descendant le plus éloigné. (dur)
La seule chose que j'ai trouvée qui s'en rapproche de près ou de loin est AspectObjectifC mais cela nécessite libffi, ce qui le rend non compatible avec iOS. Idéalement, j'aimerais que ce soit multiplateforme.
Des idées ?
<em>disclaimer : je ne fais qu'expérimenter</em>
Essayer l'idée de @bbum d'une fonction trampoline
Je pense donc avoir mis les choses en place ; j'ai le trampoline suivant qui est correctement ajouté via class_addMethod()
et il est saisi :
id dd_trampolineFunction(id self, SEL _cmd, ...) {
IMP imp = [self retrieveTheProperIMP];
self = [self retrieveTheProperSelfObject];
asm(
"jmp %0\n"
:
: "r" (imp)
);
return nil; //to shut up the compiler
}
J'ai vérifié que le soi et l'IMP sont les bonnes choses avant le PCS, et que l'IMP est la bonne chose à faire. _cmd
Les paramètres sont également correctement introduits. (en d'autres termes, j'ai correctement ajouté cette méthode).
Cependant, il se passe quelque chose. Je me retrouve parfois à passer à une méthode (qui n'est généralement pas la bonne) avec un résultat nul. self
y _cmd
. D'autres fois, je m'écrase au milieu de nulle part avec un EXC_BAD_ACCESS. Des idées ? (cela fait longtemps que je n'ai rien fait en assembleur...) Je teste cela sur x86_64.