Thursday, September 6, 2007

What is Boost.Reflection?

Boost.Reflection is similar to, and can be used together with, Boost.Extension. However, it allows for creating and using objects without having access to the definition of the class or one of its base classes (Boost.Extension requires having access to one of a class's base classes).

Features:
  1. Use arbitrary information to describe a class
  2. Instantiate a class
  3. Call its methods by arbitrary identifiers (although you can use strings to identify methods, it is possible to use any arbitrary information to select them)
  4. Fast function calls - you only have the overhead of two functions called by function pointers.
  5. Call functions without knowing what parameters they require.
  6. Containers indexed by type.
Information about Boost.Reflection is currently contained in the Extension docs. Especially check out the following:

reflection.hpp reference
reflector reference
Extension/Reflection interoperability

What is Boost.Extension?

Boost.Extension is a C++ library designed primarily to ease the creation of plugins. It allows for creating shared libraries that can be loaded by an executable, and which can implement interfaces defined in the executable. The executable can then instantiate and use these implementations.

Features:
  1. Type-safety
  2. Arbitrary information can be stored about a plugin (version info, size, requirements etc.)
  3. Fast - you access implementations through pointers to their interfaces, so you only have the normal overhead of a virtual function call
  4. Thread-safe
  5. Cross-platform (Windows, Mac, and Linux have all been tested)
  6. RTTI is optional

Tuesday, September 4, 2007

Status

I've revamped the interface for Boost.Extension, to make it more concise. The main difference is that the RTTI requirement is easier to avoid now.

Option 1:

You can have separate containers for each set of constructors for a specific interface.

Option 2:

You can declare your own type of type info - perhaps just integers or strings.

The latest change makes option one easier.

A recent checkin in Boost.Build seems to have broken the build for documentation. If you have trouble generating the documentation, you may have to wait a few days until I check the latest docs into svn.boost.org in the sandbox. I managed to get the docs compiling successfully on Ubuntu, and should have the updates posted in three to four days.

Thursday, August 30, 2007

I finally have the redesigned functionality for reflection. It's not done certainly, but the following will compile and work correctly. I'll be committing this to the SVN repository soon.

Here's how it works:

/////////////////////////////////////
// In your code that reflects some class out:

class MyClass {
public:
  int myFunction();
}
// For terseness
using namespace boost::reflections;
generic_reflector * exportMyClass() {
  reflector * myClassReflector =
  new reflector;
  // reflect an arg-less constructor
  myClassReflector->reflect_constructor();
  // reflect the member function
  // with some info about it
  // note that like boost::extensions,
  // the info parameter is templated
  // with a string as the default
  myClassReflector->reflect_method(&MyClass::myFunction, "myFunction");
  return myClassReflector;
}


///////////////////////////////
// Now in the code that will use the reflection
// (This code could be in a DLL, or the top code could be in a DLL etc)
using namespace boost::reflections;
  int main(int argc, char * argv[]) {
  // A reflection must be created with a pointer
  // to a generic_reflector
  // The reflection will destroy the generic_reflector
  reflection myReflection(exportMyClass());
  // Create an instance with a default constructor
  instance inst = myReflection.get_constructor().call();
  // Find the function with an int return value and
  // info of "myFunction" and call it.
  function func =
       myReflection.get_method("myFunction");
  // Call func on inst
  func(inst);
}



////////

Thursday, August 23, 2007

One conversation from the Boost Mailing list contained a lot of the rationale behind both libraries. The basic design goals were the following, in order of importance:

  1. Cross-platform (this is Boost - it has to be)
  2. Concise, natural interface (no macros, etc.)
  3. Minimization of dependencies on other Boost libraries
  4. Separation of optional features of the library from the primary headers
  5. Performance
Number 3 was difficult, and we've decided to probably require inclusion of Boost.Preprocessor. Constructors or other functions with many arguments require a lot of template code that is much easier to just generate using Boost.Preprocessor. Boost.Function will probably be required as well.

For some of the original discussion on some of these design decisions, see the discussion that began with Mariano's interest in writing a plugin library for the Google Summer of Code:

Current Progress

Mariano Consoni has been working on both Boost.Extension and Boost.Reflection over the summer. Our current status on these two projects:

1 - Boost.Extension is mostly complete. One piece of functionality that I have not finished is the ability to automatically close shared libraries that do not currently have any loaded plugins. The main obstacles here are preserving the current Boost.Extension syntax and overcoming some platform irregularities (on Mac OS X there are two types of dynamically linked library with very different properties - bundles and dylibs).

2 - I am currently working with the code that Mariano wrote for Boost.Reflection to make it a bit more generic and do some cleanup and performance tuning.