Bonjour à tous,
Dans le cadre d'un projet, je suis amené à mélanger du C++ et Scala. L'idée générale c'est de faire des requêtes sur des ensembles d'objet. La répartition est la suivante :
- la construction de requêtes complexes est faite en Scala
- Le C++ me sert de backend, c'est lui qui gère les objets et les interroge sur des propriétés primitives.
Pour identifier les objets dans le monde Scala, je n'ai rien trouvé de mieux que caster les adresses en std::uintptr_t
et lorsque je veux demander quelque chose, je recaste l'entier vers un pointeur éventuellement d'un sur type du type de l'objet de base
Le code ci dessous résume l'idée générale (à la différence principale que ask_foo vient de la JVM).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <iostream> #include <cstdint> struct A{ int i = 0; virtual int foo() {return i;} }; struct B : A{ int foo() override {return i+2;} }; using handle_t = std::uintptr_t; handle_t get(B& a){ return reinterpret_cast<handle_t>(&a); } void use(handle_t h){ auto p= reinterpret_cast<A*>(h); //On cast en A* std::cout << p->foo() << "\n"; } int main(int argc, char *argv[]) { B a; auto h = get(a); use(h); return 0; } |
La page de cppreference sur le sujet indique qu'on peut :
- Faire le cast
B* -> uintptr_t
- Faire le case
cast uintptr_t -> B*
- Faire le cast
B* -> A*
Est ce que pour autant fusionner les 2 dernières opérations est sans danger ? Car pour le moment, ca marche bien, mais est c'est pas juste un gros coup de chance ?
Merci ! David.