views:

293

answers:

9

I'm thinking about adding some sort of reflection capabilities to some C++ classes ( so that I wouldn't have to use RTTI ): getting names of methods, declared fields, class name ... this sort of stuff.

I was thinking about parsing existing source files, get a list of declared fields & methods, and rewrite each source file, adding this sort of information to each class.

What do you think about this approach? I'd like to do everything from scratch, since I think it's a great opportunity to learn. Would you suggest other ways of doing this?

//OFFTOPIC: is this how Qt does it?

+1  A: 

Unless you want to modify the C++ compiler or depend on vendor extensions, you will need a heap of CPP macros that build data structures.

bmargulies
+2  A: 

Check the Boost.Mirror library. It's not been accepted into Boost yet, so you'll have to download it from the Boost Vault.

The library is still in development and the docs are scarce but by studying the provided examples you might be able to achieve what you want.

EDIT: if you really want to parse your own C++ code then maybe you should consider clang

Manuel
Wow. It looks so concise and easy to use.
Eric
Are you being sarcastic?
Manuel
print_meta_data< BOOST_MIRRORED_TYPEOF("No") >
Eric
Yeah looks scary but I'm sure it's easier than writing your own C++ parser
Manuel
+2  A: 

I would fork gcc.

Paul Nathan
+2  A: 

Yes, this is how Qt does it - except it doesn't add the info to the class itself, it creates a new class called a metaclass that contains static data about the class. This is better for obvious reasons.

No pure-C++ approach will provide fully automatic reflection - the language doesn't allow it. There are many attempts, including Boost.Mirror and Boost.Reflection, but they all require boilerplate additions to your source.

Stefan Monov
+1  A: 

Take a look at article Using the C++ RTTI/Reflection APIs in the VCF to see one approach to the problem.

Nemanja Trifunovic
A: 

Maybe you can use the typeinfo library, with it you can now a object class in runtime. Example:

#include<iostream>

#include<typeinfo>
class A{};

int main()
{
A a;

std::cout<<typeid(a).name();

}

You can see more in: http://www.cplusplus.com/reference/std/typeinfo/

[]`s

Ala Livio
I don't want to use RTTI.
Geo
+1  A: 

You might find gccxml worth a look. It'll (for example) convert this to this, which means you just have to parse XML instead of C++.

There's an interesting SP&E paper which describes using gccxml in conjunction with a modified linker to "provide Java-reflection-like functionality to C++ applications in a clean and non-intrusive manner".

timday
+1  A: 

Alter the compiler to produce a static GetClass method, returning a pointer to a Class object describing the class, for every defined class.

Alter the compiler/linker to pull out the metadata needed and stuff those in special sections/symbols of the resulting executable image - much like debugging symbols are added.

GetClass would use (read/load/cache ?) the above metadata.

And yes. That's a lot of work. (And a nice side effect is it's getting you almost halway to eliminating header files - as that info could now be pulled right out of an image)

leeeroy
+1  A: 

C++ does not support reflection. The efforts from boost and RTTI are quite limited and half baked. I would not recommend them.

You mentioned that you can start from scatch. Well you can write a C++ lexer using lex/yacc, or ANTLR. Quite a lot of work, but you will learn a lot.

If writing a parser is a formidable task for you, there are some other options to get metadata of a class. Microsoft has DIA SDK that provides symbol information. Doxygen can generate XML files that you can parse to obtain the field names, method names of a class. I had some success parsing doxygen XML files.

If you only work with Microsoft platform, a viable solution is to use type library (TLB). It requires you convert the class into a interface in MS IDL. MIDL compiles the IDL into .tlb, and your application can loads the .tlb file at runtime. Your application can obtain almost all information about the class through ITypeInfo interface, properties and methods.

Sherwood Hu
Wow! Doxygen didn't even cross my mind! Cool one!
Geo