1 //~ vtl reflection, Maciej Leks, 2006 2 #include <cstring> 3 4 #include "vtl_reflection.hpp" 5 6 class Parent 7 { 8 public: 9 int a; 10 double b; 11 std::string str; 12 13 Parent() { } 14 15 double print(double number) 16 { 17 VTL_PRINT("Parent::print() = %s %f", str.c_str(), number); 18 return number; 19 } 20 21 double sum(double a, double b) 22 { 23 VTL_PRINT("Parent::sum(a,b), a=%f , b=%f", a, b); 24 return a + b; 25 } 26 27 virtual void test() { 28 VTL_PRINT("Parent::test", ""); 29 } 30 31 RTTI_DECL(Parent, RTTI_NO_BC, (RTTI_FN(print), RTTI_FN(sum), RTTI_FN(test)), (RTTI_FLD(a), RTTI_FLD(b), RTTI_FLD(str))) 32 }; 33 34 class Child : public Parent 35 { 36 public: 37 Child() { } 38 39 void test() { 40 VTL_PRINT("Child::test", ""); 41 } 42 43 RTTI_DECL(Child, RTTI_BC(Parent), (RTTI_FN(print), RTTI_FN(test)), RTTI_NO_FLDS) 44 }; 45 46 int main(int argc, char ** argv) 47 { 48 VTL_DEBUG_OFF(); 49 50 //Almost 'hello world' example 51 { 52 Child foo; 53 vtl_obj obj = foo; 54 vtl_rtti* prt = obj.get_rtti(); //get rtti of the Child class 55 56 //Let's sum two numbers 57 vtl_fn_invoker* pfn = prt->function_by_name("sum"); 58 vtl_args args; 59 60 args.push_back(2.0); 61 args.push_back(3.0); 62 63 vtl_obj sum_result = (*pfn)(obj, args); 64 65 //Let's print the result. We could print the result using sum_result object, but let's see how vtl_object passing mechanism works 66 args.clear(); //you can use vtl_args as many times as you need 67 pfn = prt->function_by_name("print"); 68 args.push_back(sum_result); //print method waits for double argument, but we also can use vtl_obj object as a wrapper 69 vtl_obj print_result = (*pfn)(obj, args); 70 VTL_PRINT("Sum result is %f", *print_result.cast<double*>()); 71 } 72 73 //Let's see how inheritance works 74 { 75 Child foo; 76 Parent *p = &foo; 77 vtl_obj obj(p); 78 vtl_args args; 79 80 vtl_rtti* prt = obj.get_rtti(); 81 vtl_fn_invoker* pfn = prt->function_by_name("test"); 82 vtl_obj test_result = (*pfn)(obj, args); 83 } 84 85 //Field modification example 86 { 87 Child foo; 88 vtl_obj obj = foo; 89 vtl_rtti* prt = obj.get_rtti(); 90 91 vtl_get_set_invoker* pgsinv = prt->field_by_name("str"); 92 93 vtl_obj obj2 = std::string("My STRING"); //vtl_obj obj = "My STRING"; statement always corrupts stack. As yet do not use string constants. 94 pgsinv->set_value(obj, obj2); // 95 96 vtl_obj get_result = pgsinv->get_value(obj); 97 std::cout << "Child::str value is " << *get_result.cast<std::string*>() << "." << std::endl; 98 } 99 100 //another method of fetching rtti pointer 101 { 102 vtl_rtti* prt = Child::_get_rtti(); //another possibility of getting vtl_rtti pointer 103 } 104 105 106 return 0; 107 }