
In brief, I'd designed and implemented somehow C++ class reflection based on boost libraries. It has some unique advantages: a) it doesn't require code generator b) platform independent and compiler independent (I tested it on Windows and Linux, with vs2008 and gcc respectively) c) it's non-intrusive for the class definition, instead, you just need to declare and describe your class via some straightforward macros anywhere (header file or source file, and may be within any namespace), which also means you can wrap an external third-party library (which you have no way to touch the source codes) and reflects it classes. d) Cross shared library boundary, you can dynamic load the shared library and reflect the classes within it, without need to export any symbol manunally in C wrapper function way e) the API looks like Java reflection API
I'm interested, could we see the sources, please? Regards Hartmut --------------- http://boost-spirit.com http://stellar.cct.lsu.edu
Below is some codes snippet to have an overview of this library: -----libTest.cpp---start--- #include <iostream> #include <string>
#include <boost/reflection/reflection.hpp>
namespace test {
class AccountItf { public: virtual std::string getId() const = 0; virtual void setId(std::string id) = 0; };
#define ACCOUNT_INTERFACE_REFL_DECLARE \ BOOST_REFL_INTERFACE(test::AccountItf) \ BOOST_REFL_CONST_METHOD(getId, std::string()) \ BOOST_REFL_METHOD(setId, void(std::string))
class Account : public AccountItf { std::string id; public: Account() : age(0) {} Account(std::string id, unsigned int age) : id(id), age(age) {} static void echo(Account* acct, std::string banner) { std::cout << banner + ": " << acct->getId() << std::endl; } std::string getId() const { return id; } void setId(std::string id) { this->id = id; } public: unsigned int age; };
//Account declaration for used by reflection //this declaration can be placed anywhere, even the header file BOOST_REFL_CLASS ( (test)(Account), //constructors BOOST_REFL_CONSTRUCTOR() BOOST_REFL_CONSTRUCTOR(std::string id, unsigned int age) //static methods BOOST_REFL_STATIC_METHOD(echo, void (Account* acct, std::string banner)) //properties BOOST_REFL_PROPERTY(age, unsigned int) //derived Inteface ACCOUNT_INTERFACE_REFL_DECLARE ) }
-----libTest.cpp----end-- Compile the libTest.cpp into the libTest.dll or libTest.so.
-----main.cpp----start-- #include <iostream> #include <string> using namespace std;
#include <boost/reflection/reflection.hpp> using namespace boost::reflection;
#if defined(BOOST_WINDOWS) #include <Windows.h> #else #include <dlfcn.h> #endif
int main(int argc, char* argv[]) { #if defined(BOOST_WINDOWS) LoadLibraryA (argv[1]); #else dlopen(argv[1], RTLD_NOW); #endif Class t = Class::forName("test.Account");
boost::any obj = t.newInstance(std::string("Account-id-100"), (unsigned int)26);
t.invokeStatic("echo", obj, std::string("TEST"));
TypeInfoArray tArray; tArray.push_back(BOOST_REFL_TYPEID(std::string)); Method m1 = t.getMethod("setId", tArray); m1.invoke(obj, std::string("Account-id-200"));
Method m2 = t.getMethod("getId"); boost::any ret = m2.invoke(obj); std::cout << "Account getId(): " << boost::any_cast<std::string>(ret) << std::endl;
Property prop = t.getProperty("age"); prop.set(obj, (unsigned int)30); std::cout << "Account age: " << boost::any_cast<unsigned int>(prop.get(obj)) << std::endl;
return 0; } -----main.cpp---end---
Compile the main.cpp into the executable and execute it: ./main libTest.dll
it will output: TEST: Account-id-100 Account getId(): Account-id-200 Account age: 30
This library is very useful for framework-level design which needs C++ reflection, e.g. recently I'm working on somehow SQL mapping library for C++, just like MyBatis, and reflection makes possible to invoke the getter/setter of the object instances of classes specified in the XML file.
Regards, JinHua
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost