Is there any interest in a library which solves C++ class reflection feature just like Java does?

Hi, 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 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

Hi,
In brief, I'd designed and implemented somehow C++ class reflection based on boost libraries.
I am interested. Could you detail how it differs from BOOST_*FUSION*_ADAPT_* STRUCT* in boost::fusion ? It seems very similar to me.
It has some unique advantages: a) it doesn't require code generator
Well ... I'd prefer that a code generater be provided: Your syntax is not that lightweight, you can compare with boost::reflect that is a non proposed library (link https://github.com/bytemaster/boost_reflect). If you want to reflect a large number of classes, then your solution is not very maintenable (as all solutions without a code generator). One more thing: your solution is "runtime" reflection, I think in C++ a compile time API would make more sense, though, I must say there are advantages for both. Regards, Julien

Hi, I just have a quick look at the boost::fusion. The declaration syntax is a bit similar, but they are completely different things, I think. And the my library do not use boost::fusion. Also have a quick look at the boost::reflect, and I found it's a different style to fulfill the reflection: a) my way is non-intrusive, which means it makes no assumption about your class, e.g. inheritance, or implements any interfaces. Any public class members (member functions) of any type (even the C++ reference) can be reflected. But the boost::reflect seems to be focus on the interface-oriented reflection. b) in my way, you just need to declare your class via dedicated macros, and do nothing else, then you can use Java-like reflection API to reflect and use your classes at run time. And the API do not need any initialization before you begin to use. All the declared classes will be registered automatically. c) The declaration and reflection is separated. In my example, you can see that the declaration resides in the standalone shared library, while the reflection API usage resides in any other program, in which program you do not need to include any concrete class header file, because that's where the reflection magic happens. But the boost::reflect needs to know about the interface definition obviously. d) when the compiler compiles the declaration, it will raises errors if the declaration is invalid, e.g. the prototype doesn't match the class definition. So it's type-safe. Moreover, the reflection API will raise exceptions if you try to launch some invalid reflection, e.g. non-exist method, wrong method prototype. e) the declaration is flexible enough. you can place the declaration anywhere (and within any namespace), which means you don't have to place it into one single source file. in fact, you don't need to care about the ODR (One-Definition-Rule) violation, and it will eliminate the duplicated class registration, and that's why I said you can place the declaration within the header file, which may be included within any compile unit. You can even place the same declaration both in the shared library and the executable. Regards, JinHua 2011/12/6 Julien Nitard <julien.nitard@m4tp.org>
Hi,
In brief, I'd designed and implemented somehow C++ class reflection based on boost libraries.
I am interested. Could you detail how it differs from BOOST_*FUSION*_ADAPT_* STRUCT* in boost::fusion ? It seems very similar to me.
It has some unique advantages: a) it doesn't require code generator
Well ... I'd prefer that a code generater be provided: Your syntax is not that lightweight, you can compare with boost::reflect that is a non proposed library (link https://github.com/bytemaster/boost_reflect). If you want to reflect a large number of classes, then your solution is not very maintenable (as all solutions without a code generator).
One more thing: your solution is "runtime" reflection, I think in C++ a compile time API would make more sense, though, I must say there are advantages for both.
Regards,
Julien
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Tue, Dec 6, 2011 at 12:40 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi,
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
Interesting. Have you thought about how this would be better implemented as part of the compiler, so that you don't have to actually explicitly reflect a type using macros?
b) platform independent and compiler independent (I tested it on Windows and Linux, with vs2008 and gcc respectively)
I guess since this is all runtime values, as long as you're using standard C++ it shouldn't be a problem. Interesting to note anyway.
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.
I like this.
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
Cool
e) the API looks like Java reflection API
Okay, this part I'm not excited about. I have two questions here: 1) How do you handle invalidation of objects that are instantiated from a certain type that's reflected when the reflected type changes? How do you handle say when a new method is added? How do you handle changing method signatures? 2) In case of a name collision, how does your library behave? I'm interested because I'm working on a paper that addresses this issue with changes to the language in mind. It's interesting to see yet another way people are solving this with a library solution. Cheers -- Dean Michael Berris http://goo.gl/CKCJX

Hi, 1) Platform-independent and Compiler-independent is important, then the reflection can be applied to tons of C++ applications. In fact, it's not so possible and feasible to change the compiler, regarding many reasons, e.g. you have no way to change some compilers with commercial licensing and closed-source, e.g. vs2008. 2) As known, C++ is statically typed language, so I think it's meaningless and impossible to change the type at runtime. Of course, the declaration for reflection may only cover a subset of the class definition, as normally you just need to reflect some essential members for use by other application logic.If the declaration changes, e.g. reflect one more method, you need to re-compile it. Since the reflection supports shared library dynamic loading and works across the shared library, so you just need to re-compile the affected part. 3) Due to the flexibility of the declaration, there may exists multiple reflection registration of the same class, e.g. when you place the declaration within some header file, and that header file is included in different compile unit, even among different shared library compilation. The solution is to keep only one registration for the same class (identified by the qualified class name) at run-time, and discards others. Which registration to be kept is in random and unknown, but that's not a problem as long as they are identical. So it's recommended to place the declaration in one header file. Of course, if there occurs the naming collision (different class definitions but with the same class name), the solution is the same: keep only one and discards others. But that's a bad development practise, and I think we should avoid it as much as possible. So that's beyond the reflection topic. Regards, JinHua 2011/12/6 Dean Michael Berris <mikhailberis@gmail.com>
On Tue, Dec 6, 2011 at 12:40 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi,
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
Interesting. Have you thought about how this would be better implemented as part of the compiler, so that you don't have to actually explicitly reflect a type using macros?
b) platform independent and compiler independent (I tested it on Windows and Linux, with vs2008 and gcc respectively)
I guess since this is all runtime values, as long as you're using standard C++ it shouldn't be a problem. Interesting to note anyway.
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.
I like this.
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
Cool
e) the API looks like Java reflection API
Okay, this part I'm not excited about.
I have two questions here:
1) How do you handle invalidation of objects that are instantiated from a certain type that's reflected when the reflected type changes? How do you handle say when a new method is added? How do you handle changing method signatures?
2) In case of a name collision, how does your library behave?
I'm interested because I'm working on a paper that addresses this issue with changes to the language in mind. It's interesting to see yet another way people are solving this with a library solution.
Cheers
-- Dean Michael Berris http://goo.gl/CKCJX
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Tue, Dec 6, 2011 at 2:40 AM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi,
Hi,
In brief, I'd designed and implemented somehow C++ class reflection based on boost libraries.
Did you have a look at the Mirror reflection utilities ?
It has some unique advantages: a) it doesn't require code generator
Good, but it is not so unique
b) platform independent and compiler independent (I tested it on Windows and Linux, with vs2008 and gcc respectively)
Nice,
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.
This is not unique either
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
I believe (and I have some expertise in using and implementing reflection in C++ to base that belief upon) that the basic reflection should compile-time and any run-time reflection should be built on top of that.
e) the API looks like Java reflection API
I don't think that this is a good idea, and I've seen several (scientific) papers where people don't think it either. BR Matus

Hi, I have a quick look at the Mirror reflection utilities, although no deep investigation, I have some opinions about it: a) complex reflection declaration syntax (e.g. to describe the prototype of some method, it needs to use macro per parameter, but in my way, it's more easier and native: you just need to copy and parse the prototype from the class definition) b) depends on C++11 features (as mentioned in the web site, It has been tested and is currently known to work with the gcc 4.5.1 and higher), but my way does not require new versions of C++ standards, so it supports VC7 or higher, and all gcc versions. c) the source codes of the Mirror reflection utilities is a bit huge and complex than my one: my reflection library has only 3 header files and 1 source file, and the codes are about 1200 lines. Regards, JinHua 2011/12/6 Matus Chochlik <chochlik@gmail.com>
On Tue, Dec 6, 2011 at 2:40 AM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi,
Hi,
In brief, I'd designed and implemented somehow C++ class reflection based on boost libraries.
Did you have a look at the Mirror reflection utilities ?
It has some unique advantages: a) it doesn't require code generator
Good, but it is not so unique
b) platform independent and compiler independent (I tested it on Windows and Linux, with vs2008 and gcc respectively)
Nice,
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.
This is not unique either
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
I believe (and I have some expertise in using and implementing reflection in C++ to base that belief upon) that the basic reflection should compile-time and any run-time reflection should be built on top of that.
e) the API looks like Java reflection API
I don't think that this is a good idea, and I've seen several (scientific) papers where people don't think it either.
BR
Matus
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Tue, Dec 6, 2011 at 2:37 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi,
OK let me say this so you don't get me wrong: I welcome any attempt to add reflection to C++, I would very much like to have reflection in the C++ standard with the full support of the compiler, and I don't care on whose design it is based. What I care about is that it is done properly, i.e. that it is not tailored for a specific goal ORM, Serialization, RPC, GUI geneation, parser generation, whatever .. but that it would support all of these and much more. It should provide as much meta-data as possible even if some of it might not be obviously usable in some scenario (it might be in others), etc. It also should be compile-time because then you can use it with all the great meta-programming tools implemented in Boost and elsewhere. If you have a solid compile-time foundation you can implement run-time reflection even, dynamically loadable easily.
I have a quick look at the Mirror reflection utilities, although no deep investigation, I have some opinions about it:
a) complex reflection declaration syntax (e.g. to describe the prototype of some method, it needs to use macro per parameter, but in my way, it's more easier and native: you just need to copy and parse the prototype from the class definition)
The syntax is complex only if you need to specify all details manually. There are however the quick-registering macros that simplify the registering quite a lot.
b) depends on C++11 features (as mentioned in the web site, It has been tested and is currently known to work with the gcc 4.5.1 and higher), but my way does not require new versions of C++ standards, so it supports VC7 or higher, and all gcc versions.
C++11 is a standard now and Mirror (AFAICT) doesn't use anything gcc-specific. I know that the release cycles for compilers are quite long, but I hope that we'll get good if not full support for C++11 soon.
c) the source codes of the Mirror reflection utilities is a bit huge and complex than my one: my reflection library has only 3 header files and 1 source file, and the codes are about 1200 lines.
It is true that Mirror is a big library, but to do some basic things you certainly don't need to include every header. Much of the source code implements "higher-level" tools on top of the basic reflection. There is still some mess in the header organization, but I want to have all that fixed in future releases.
Regards, JinHua

Hi, ok, it's hard to explain every detail before I publish my codes somewhere (I'm preparing to publish it). Anyway, let me introduce some principles of my understanding of the "reflection": a) it should be simple and clear enough, which means it doesn't require the user to get much background knowledge before he can apply the library into his application. So either the macro declaration or the API should be clear or even be familiar with (that's why I choose Java style API, and I care about practicability). I hope learning the library usage just like learning how to write a "hello world". b) the reflection should be general, not specific to any domain purpose c) the reflection should be real reflection, i.e. you can reflect your declared class at runtime specified by qualified class name string, and you don't need to make your program compiled with any C++ codes related to that class, e.g. class definition and implementation (in my example, the main program is the program to use the reflected classes, and it knows nothing about the class definition and implementation, which in turn is compiled into another shared library), and I think that's the magic of the reflection. I know there exists many reflection implementation, and every implementation has its advantages and disadvantages, I think. And my implementation is a light-weighted but useful enough one, I believe. Regards, JinHua 2011/12/7 Matus Chochlik <chochlik@gmail.com>
On Tue, Dec 6, 2011 at 2:37 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi,
OK let me say this so you don't get me wrong: I welcome any attempt to add reflection to C++, I would very much like to have reflection in the C++ standard with the full support of the compiler, and I don't care on whose design it is based.
What I care about is that it is done properly, i.e. that it is not tailored for a specific goal ORM, Serialization, RPC, GUI geneation, parser generation, whatever .. but that it would support all of these and much more. It should provide as much meta-data as possible even if some of it might not be obviously usable in some scenario (it might be in others), etc.
It also should be compile-time because then you can use it with all the great meta-programming tools implemented in Boost and elsewhere. If you have a solid compile-time foundation you can implement run-time reflection even, dynamically loadable easily.
I have a quick look at the Mirror reflection utilities, although no deep investigation, I have some opinions about it:
a) complex reflection declaration syntax (e.g. to describe the prototype of some method, it needs to use macro per parameter, but in my way, it's more easier and native: you just need to copy and parse the prototype from the class definition)
The syntax is complex only if you need to specify all details manually. There are however the quick-registering macros that simplify the registering quite a lot.
b) depends on C++11 features (as mentioned in the web site, It has been tested and is currently known to work with the gcc 4.5.1 and higher), but my way does not require new versions of C++ standards, so it supports VC7 or higher, and all gcc versions.
C++11 is a standard now and Mirror (AFAICT) doesn't use anything gcc-specific. I know that the release cycles for compilers are quite long, but I hope that we'll get good if not full support for C++11 soon.
c) the source codes of the Mirror reflection utilities is a bit huge and complex than my one: my reflection library has only 3 header files and 1 source file, and the codes are about 1200 lines.
It is true that Mirror is a big library, but to do some basic things you certainly don't need to include every header. Much of the source code implements "higher-level" tools on top of the basic reflection. There is still some mess in the header organization, but I want to have all that fixed in future releases.
Regards, JinHua
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Le 07/12/11 10:28, Matus Chochlik a écrit :
On Tue, Dec 6, 2011 at 2:37 PM, jinhua luo<ljh.home.king@gmail.com> wrote:
Hi, OK let me say this so you don't get me wrong: I welcome any attempt to add reflection to C++, I would very much like to have reflection in the C++ standard with the full support of the compiler, and I don't care on whose design it is based.
What I care about is that it is done properly, i.e. that it is not tailored for a specific goal ORM, Serialization, RPC, GUI geneation, parser generation, whatever .. but that it would support all of these and much more. It should provide as much meta-data as possible even if some of it might not be obviously usable in some scenario (it might be in others), etc.
It also should be compile-time because then you can use it with all the great meta-programming tools implemented in Boost and elsewhere. If you have a solid compile-time foundation you can implement run-time reflection even, dynamically loadable easily.
I have a quick look at the Mirror reflection utilities, although no deep investigation, I have some opinions about it: a) complex reflection declaration syntax (e.g. to describe the prototype of some method, it needs to use macro per parameter, but in my way, it's more easier and native: you just need to copy and parse the prototype from the class definition) The syntax is complex only if you need to specify all details manually. There are however the quick-registering macros that simplify the registering quite a lot.
I don't think that a compile-time reflection library is in competition with a run-time library. Both approaches are complementary, and I'm sure that the Boost community will appreciate both approaches if the library is well designed.
b) depends on C++11 features (as mentioned in the web site, It has been tested and is currently known to work with the gcc 4.5.1 and higher), but my way does not require new versions of C++ standards, so it supports VC7 or higher, and all gcc versions. C++11 is a standard now and Mirror (AFAICT) doesn't use anything gcc-specific. I know that the release cycles for compilers are quite long, but I hope that we'll get good if not full support for C++11 soon.
The fact that a library need c++11 support only restrict the compilers that can be used with. I guess that C++11 only libraries are welcome in Boost. Of course, if the library can be used on C++98 compilers with minor limitations, the number of potential users will be higher. So please, don't start a discussion stating that we need a compile-time/run-time or c++11/c++98 library. All the combinations have its usage, each one with its advantages and liabilities. Best, Vicente

2011/12/7 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
So please, don't start a discussion stating that we need a compile-time/run-time or c++11/c++98 library. All the combinations have its usage, each one with its advantages and liabilities.
Point is that it's possible to build runtime reflection on top of compile-time reflection, but the opposite isn't true. One can even claim that runtime reflection *must* be implemented on top of compile-time reflection, so proposing *just* runtime reflection is pointless. Roman Perepelitsa.

On 12/07/11 06:51, Roman Perepelitsa wrote:
2011/12/7 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
So please, don't start a discussion stating that we need a compile-time/run-time or c++11/c++98 library. All the combinations have its usage, each one with its advantages and liabilities.
Point is that it's possible to build runtime reflection on top of compile-time reflection, but the opposite isn't true. One can even claim that runtime reflection *must* be implemented on top of compile-time reflection, so proposing *just* runtime reflection is pointless. Hi Roman,
Could you please show an example run-time reflection being build on top of compile-time reflection or explain more on why this is true? TIA. -regards Larry

2011/12/7 Larry Evans <cppljevans@suddenlink.net>
On 12/07/11 06:51, Roman Perepelitsa wrote:
2011/12/7 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
So please, don't start a discussion stating that we need a compile-time/run-time or c++11/c++98 library. All the combinations have its usage, each one with its advantages and liabilities.
Point is that it's possible to build runtime reflection on top of compile-time reflection, but the opposite isn't true. One can even claim that runtime reflection *must* be implemented on top of compile-time reflection, so proposing *just* runtime reflection is pointless. Hi Roman,
Could you please show an example run-time reflection being build on top of compile-time reflection
Mirror is such a library.
or explain more on why this is true?
I think it's a good question which deserves a good answer, but due personal (or rather work) reasons I can't provide it right now. I'll try to get back to it next weekend. Roman Perepelitsa.

On Wed, Dec 7, 2011 at 2:21 PM, Roman Perepelitsa <roman.perepelitsa@gmail.com> wrote:
2011/12/7 Larry Evans <cppljevans@suddenlink.net>
On 12/07/11 06:51, Roman Perepelitsa wrote:
2011/12/7 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
So please, don't start a discussion stating that we need a compile-time/run-time or c++11/c++98 library. All the combinations have its usage, each one with its advantages and liabilities.
Point is that it's possible to build runtime reflection on top of compile-time reflection, but the opposite isn't true. One can even claim that runtime reflection *must* be implemented on top of compile-time reflection, so proposing *just* runtime reflection is pointless. Hi Roman,
Could you please show an example run-time reflection being build on top of compile-time reflection
Mirror is such a library.
Compare for example this: http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/mirror/html/d5/d... with this: http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/lagoon/html/df/d... both applications do similar things; print the "kind" (type, namespace, template, etc.) of a member of a namespace and its name. The first uses compile-time reflection, the second uses run-time reflection and the run-time meta-objects are based completely on the compile-time meta-objects. Also, in the run-time case, there is nothing (that I know of) preventing you from using just the meta-object interfaces in your application, compiling their implementations (the actual meta-objects) into a separate dynamic library / shared object and loading and querying them on demand from the application. for more examples of compile-time vs. run-time reflection see here: http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/mirror/html/exam... and here: http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/lagoon/html/exam... or just start a the main page of the docs: http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/ Best, Matus

Hi Matus, Could you write some codes to implement the same example I showed in my first mail? That is, define a concrete class in the shared library, and declare/register it there, while the main program just dynamically loads the shared library (note that do not need any initialization, just dlopen is enough, do not need any symbol exported there and be loaded via dlsym), reflects the class, invoke its methods, access its members. Then we can have more clear comparison regarding the same context between two libraries. Regards, JinHua 2011/12/7 Matus Chochlik <chochlik@gmail.com>
On Wed, Dec 7, 2011 at 2:21 PM, Roman Perepelitsa <roman.perepelitsa@gmail.com> wrote:
2011/12/7 Larry Evans <cppljevans@suddenlink.net>
On 12/07/11 06:51, Roman Perepelitsa wrote:
2011/12/7 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
So please, don't start a discussion stating that we need a compile-time/run-time or c++11/c++98 library. All the combinations have its usage, each one with its advantages and liabilities.
Point is that it's possible to build runtime reflection on top of compile-time reflection, but the opposite isn't true. One can even claim that runtime reflection *must* be implemented on top of compile-time reflection, so proposing *just* runtime reflection is pointless. Hi Roman,
Could you please show an example run-time reflection being build on top of compile-time reflection
Mirror is such a library.
Compare for example this:
http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/mirror/html/d5/d...
with this:
http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/lagoon/html/df/d...
both applications do similar things; print the "kind" (type, namespace, template, etc.) of a member of a namespace and its name.
The first uses compile-time reflection, the second uses run-time reflection and the run-time meta-objects are based completely on the compile-time meta-objects.
Also, in the run-time case, there is nothing (that I know of) preventing you from using just the meta-object interfaces in your application, compiling their implementations (the actual meta-objects) into a separate dynamic library / shared object and loading and querying them on demand from the application.
for more examples of compile-time vs. run-time reflection see here:
http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/mirror/html/exam...
and here:
http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/lagoon/html/exam...
or just start a the main page of the docs:
http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/
Best,
Matus
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Wed, Dec 7, 2011 at 2:52 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi Matus,
Could you write some codes to implement the same example I showed in my first mail? That is, define a concrete class in the shared library, and declare/register it there, while the main program just dynamically loads the shared library (note that do not need any initialization, just dlopen is enough, do not need any symbol exported there and be loaded via dlsym), reflects the class, invoke its methods, access its members.
JinHua, I'm unfortunately up to my neck in other projects right now :), so I cannot come up with a working example right away, but I may try if I'll have some free time. But anyway, I don't think that the constraints that the library should not export anything explicitly are necessary. It always can be done with a macro in the library code. Also I don't see why the application should not use dlsym / GetProcAddress (at least indirectly). This could easily be hidden in the reflection code that the app uses to get the meta-data. Best, Matus
Then we can have more clear comparison regarding the same context between two libraries.
Regards, JinHua

Hi Matus, If the reflection requires explicit symbol export/import, then it's not so flexible. For example, then you must place the Marco declaration within one and only one source file due to the ODR (One-Definition-Rule), but can not place it anywhere, e.g. the header file. However, the latter one is more reasonable and convenient, which makes your macro declaration just follows its class definition together. Another problem is if there exists many classes to be reflected, then your library should export an auxiliary symbol per class, which is not a good thing, I think, at least it will cause symbol naming collision. Last but not least, consider such scenario: the main program declares some classes, and the codes within loaded library try to reflect them and use them, i.e. the roles exchanges between them. Then it's not so possible to export some symbols in the executable on some platforms for access by the shared library (of course, on Linux, you can export symbols from executable via "-Wl,-E" linker options, but that's also bad development practise). Regards, JinHua 2011/12/7 Matus Chochlik <chochlik@gmail.com>
Hi Matus,
Could you write some codes to implement the same example I showed in my first mail? That is, define a concrete class in the shared library, and declare/register it there, while the main program just dynamically loads the shared library (note that do not need any initialization, just dlopen is enough, do not need any symbol exported there and be loaded via
On Wed, Dec 7, 2011 at 2:52 PM, jinhua luo <ljh.home.king@gmail.com> wrote: dlsym),
reflects the class, invoke its methods, access its members.
JinHua,
I'm unfortunately up to my neck in other projects right now :), so I cannot come up with a working example right away, but I may try if I'll have some free time.
But anyway, I don't think that the constraints that the library should not export anything explicitly are necessary. It always can be done with a macro in the library code.
Also I don't see why the application should not use dlsym / GetProcAddress (at least indirectly). This could easily be hidden in the reflection code that the app uses to get the meta-data.
Best,
Matus
Then we can have more clear comparison regarding the same context between two libraries.
Regards, JinHua
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Wed, Dec 7, 2011 at 3:46 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi Matus,
If the reflection requires explicit symbol export/import, then it's not so flexible. For example, then you must place the Marco declaration within one and only one source file due to the ODR (One-Definition-Rule), but can not place it anywhere, e.g. the header file. However, the latter one is more reasonable and convenient, which makes your macro declaration just follows its class definition together.
I get it now, you were talking about exporting something from the library *per class*, yes that would be bad. Mirror however requires only one function *per library* so ODR would not be a problem.
Another problem is if there exists many classes to be reflected, then your library should export an auxiliary symbol per class, which is not a good thing, I think, at least it will cause symbol naming collision. Last but not least, consider such scenario: the main program declares some classes, and the codes within loaded library try to reflect them and use them, i.e. the roles exchanges between them. Then it's not so possible to export some symbols in the executable on some platforms for access by the shared library (of course, on Linux, you can export symbols from executable via "-Wl,-E" linker options, but that's also bad development practise).
Matus

Hi, Another quick question: Could you show how to invoke one specific method (can be any prototype) of the reflected class? Do you need to cast it into that real class type before you can invoke it? If so, then I think it doesn't satisfies what I mention that "the main program does not need to include any compile-time information of the reflected class, e.g. class header file". I do not see some clear example about this on your website, so I am wondering that. BR JinHua 2011/12/7 Matus Chochlik <chochlik@gmail.com>
On Wed, Dec 7, 2011 at 3:46 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi Matus,
If the reflection requires explicit symbol export/import, then it's not so flexible. For example, then you must place the Marco declaration within one and only one source file due to the ODR (One-Definition-Rule), but can not place it anywhere, e.g. the header file. However, the latter one is more reasonable and convenient, which makes your macro declaration just follows its class definition together.
I get it now, you were talking about exporting something from the library *per class*, yes that would be bad.
Mirror however requires only one function *per library* so ODR would not be a problem.
Another problem is if there exists many classes to be reflected, then your library should export an auxiliary symbol per class, which is not a good thing, I think, at least it will cause symbol naming collision. Last but not least, consider such scenario: the main program declares some classes, and the codes within loaded library try to reflect them and use them, i.e. the roles exchanges between them. Then it's not so possible to export some symbols in the executable on some platforms for access by the shared library (of course, on Linux, you can export symbols from executable via "-Wl,-E" linker options, but that's also bad development practise).
Matus
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Wed, Dec 7, 2011 at 4:03 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi,
Another quick question: Could you show how to invoke one specific method (can be any prototype) of the reflected class?
This is not yet implemented in the run-time layer but basically it will follow the way constructors are called (since constructors are functions too). Generally when you want to construct an instance of a class which may have several different constructors (there is a parallel with function overloads), some of which may require parameters, you need to supply the data for the construction in some form. Currently supported are XML, JSON, a C++-like script, relational database, and a wxWidgets-based GUI but the basic mechanism is extensible and is completely independent from the reflected classes. See for example this: http://kifri.fri.uniza.sk/~chochlik/mirror-lib/html/doxygen/lagoon/html/d3/d... The important things you need to do are: 1) get the data from which you want to construct the class. In that example above it is loaded from a JSON string (hardcoded for simplicity). 2) get the meta_class for a particular class auto meta_person = reflected_class<test::person>(); The above uses the real class but there is not reason why the line above could not look something like this (it is just not implemented) auto meta_person = reflected_class("test::person"); 3) then you instantiate something called a factory-builder and factory-input-data. 4) you build a factory for the person type using the builder and the meta-class reflecting the person class. The builder basically uses the meta-data provided by the meta-class to construct a specialized JSON parser and some code for calling the constructor (function) 5) you feed the input data (the JSON string) into the factory The factory takes a look at the input data chooses which constructor to use (by matching the data to the available constructor signatures) 6) The factory calls the selected constructor and constructs an instance of person (wrapped in a untyped pointer of boost::any) The invocation of (member) functions will work in a similar fashion. You provide the input data in some form, the Invoker will use factories like the described above to construct the parameters and call the function you want. You can specify which one or have the invoker select it automatically.
Do you need to cast it into that real class type before you can invoke it?
The example above does it but generally, No if you don't want to.
If so, then I think it doesn't satisfies what I mention that "the main program does not need to include any compile-time information of the reflected class, e.g. class header file". I do not see some clear example about this on your website, so I am wondering that.
Yes, the docs are still messy.
BR JinHua
Matus

2011/12/7 Matus Chochlik <chochlik@gmail.com>
On Wed, Dec 7, 2011 at 4:03 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi,
Another quick question: Could you show how to invoke one specific method (can be any prototype) of the reflected class?
This is not yet implemented in the run-time layer but basically it will follow the way constructors are called (since constructors are functions too).
Generally when you want to construct an instance of a class which may have several different constructors (there is a parallel with function overloads), some of which may require parameters, you need to supply the data for the construction in some form.
ok, my reflection also supports overloaded methods or constructors, and the invoke will choose the one which matches the types of input parameters.
Currently supported are XML, JSON, a C++-like script, relational database, and a wxWidgets-based GUI but the basic mechanism is extensible and is completely independent from the reflected classes.
As mentioned, I'm working on SQL mapping (like MyBatis) project based on
my reflection. And in fact, it also supports XML, JSON mapping regarding the same reflection functionality. Anyway, I'm looking forward to your complete example. Then we could have more actual comparision. BR JinHua

Hi Matus, Just to clarify that my reflection does not need to make any assumption about the reflected class, i.e. inherited from any virtual base class (interface) or not, and the reflection API do not need to know anything about the reflected class definition or its base interface class if any. So you can see that the main program in my example does not include any compile-time information about the reflected class. And the shared library does not export any symbol (in fact the registration just happens when you dlopen that library). Regards, JinHua 2011/12/7 jinhua luo <ljh.home.king@gmail.com>
Hi Matus,
Could you write some codes to implement the same example I showed in my first mail? That is, define a concrete class in the shared library, and declare/register it there, while the main program just dynamically loads the shared library (note that do not need any initialization, just dlopen is enough, do not need any symbol exported there and be loaded via dlsym), reflects the class, invoke its methods, access its members.
Then we can have more clear comparison regarding the same context between two libraries.
Regards, JinHua

On Wed, Dec 7, 2011 at 3:21 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi Matus,
Just to clarify that my reflection does not need to make any assumption about the reflected class, i.e. inherited from any virtual base class (interface) or not, and the reflection API do not need to know anything about the reflected class definition or its base interface class if any. So you can see that the main program in my example does not include any compile-time information about the reflected class.
Neither does Mirror, it is non-intrusive and does not require the reflected classes to inherit from any specific base class. And the shared library
does not export any symbol (in fact the registration just happens when you dlopen that library).
Does this also work with LoadLibrary/GetProcAddress ? What are the advantages ? BR Matus

Hi, Yes, it also works with LoadLibrary/GetProcAddress Regards, JinHua 2011/12/7 Matus Chochlik <chochlik@gmail.com>
On Wed, Dec 7, 2011 at 3:21 PM, jinhua luo <ljh.home.king@gmail.com> wrote:
Hi Matus,
Just to clarify that my reflection does not need to make any assumption about the reflected class, i.e. inherited from any virtual base class (interface) or not, and the reflection API do not need to know anything about the reflected class definition or its base interface class if any. So you can see that the main program in my example does not include any compile-time information about the reflected class.
Neither does Mirror, it is non-intrusive and does not require the reflected classes to inherit from any specific base class.
And the shared library
does not export any symbol (in fact the registration just happens when you dlopen that library).
Does this also work with LoadLibrary/GetProcAddress ? What are the advantages ?
BR
Matus
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

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

Hi, I'm preparing to publish this reflection project, e.g. figure out where to host it, which may take some time. Meanwhile, I'm busy working on a SQL mapping (similar to MyBatis) project which is based on this reflection project. Regards, JinHua 2011/12/7 Hartmut Kaiser <hartmut.kaiser@gmail.com>
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
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (8)
-
Dean Michael Berris
-
Hartmut Kaiser
-
jinhua luo
-
Julien Nitard
-
Larry Evans
-
Matus Chochlik
-
Roman Perepelitsa
-
Vicente J. Botet Escriba