Saturday, July 7, 2012

Have you ever dreamed about Aspect-Oriented Programming (AOP) in your C++ program? Like, logging specific actions or implementing per-method security or intercept it and validate parameters? Ever wanted to see a live trace of all functions which are executed along with their parameters?


COM, virtual method tables and assembly language together makes for a wonderful possibility. Here's an output from a test program that traces every call to a COM object - including interface and method names, parameter and return values. This is possible because:
1. COM works via vtbls
2. COM objects are created via single points - a special function where we do the magic of replacing object's vtbl pointer. This means calling OurCoCreateInstance instead of the system one. Please adjust your ATL.
3. We create our special virtual table using array of assembly-level functions.
4. They are assembly-level because we want to do magic. C compiler will mess with our beloved registers.
5. What we basically do is call our tracing methods, then restore stack as if we were not called (not even IP is on the stack) and then we do a call to the native method.
5a. We only have this at the time of call, so we lookup in the global table by this pointer to get the saved original vtbl. There we can get the method.
6. Most people consider doing jmp here. But we want return values and we want call. There're few problems here:
6a. We have to save the original IP that was first on the stack.
6b. However, we don't own the stack at all because it will be used by the called real function "as is". It will overwrite it. No space on stack belongs to us. This means that we can't even save registers that we used. Not a single one.
7. A solution to this - allocate space in heap (on each call) and store registers there. Restore them after the call, including copying the original IP pointer to its place on the stack. Call preserves E/RSI, DI, BP so one of them will hold our heap data pointer.
7a. Or we can have a separate stack somewhere and not allocate heap on each call. But this is not thread safe. Profile as neccessary. Maybe you want to go this route. Consider TLS and prepare for a sleepless night.

Also, we only need to create and initialize a wrapper object once per interface, not once per object.
After Release call we check our own refcounter, deleting as neccessary.
After each QueryInterface call we need to apply our magic to the returned object, if neccessary. Interfaces shares vtbl with derived classes so we check if object's vtbl already points to our fake vtbl. If so, don't do nothing.

All in all, I wonder if MS uses the same magic for marshalling and remote COM.

New vtbl wrap: 0x804c290
Objects count for IStream: 1
Wrapped IStream: native: 0x9cff020, wrapped: 0x9cff030
=> IStream::AddRef
Native AddRef
==> IStream::AddRef
Native AddRef
<== IStream::AddRef = 1
<= IStream::AddRef = 1
Calling...
=> IStream::QueryInterface
Native QI: QI
<= IStream::QueryInterface = 0
=> IStream::Write("write")
Stream Write: write
Testing inner stream
Objects count for IStream: 2
Wrapped IStream: native: 0x9cff418, wrapped: 0x9cff030
==> IStream::AddRef
Native AddRef
<== IStream::AddRef = 1
==> IStream::Write("Inner Write call")
Stream Write: Inner Write call
Testing inner stream
<== IStream::Write = 33
==> IStream::Release
Native Release
<== IStream::Release = 0
Release returned 0, objects left: 1
<= IStream::Write = 3
=> IStream::Read("write")
Stream Read: write
<= IStream::Read = 4
=> IStream::QueryInterface
Native QI: QI
<= IStream::QueryInterface = 0
=> IStream::Release
Native Release
<= IStream::Release = 0
Release returned 0, objects left: 0
Finished OK

Wednesday, February 1, 2012

Specialize C++ constructor template parameter by base type

If we want to restrict C++ templated member function type, we can use return type:

class A
{
   template <typename T>
   typename std::enable_if<std::is_base_of<base, T>::value>::type function(T arg) {}
};

function will be considered only if T is derived from base. But what in case of A::A() constructor? There's no return value.

In this case we can use a dummy parameter with default value:

class A
{
   template <typename T>
   A(T arg, typename std::enable_if<std::is_base_of<base, T>::value>::type *dummy = 0) {}
};

This constructor will be used only for types derived from base, and we can still invoke it with single parameter. Even more, this constructor will still be used in implicit type conversions:

A variable = derived_from_base();

Friday, September 23, 2011

Char is not string

Did you know that
(list.Count() + ' ').ToString()
produces "33"
and
list.Count() + " "
produces "1 "?

Monday, March 28, 2011

Bind to entity Id

Since I started to use ASP.NET MVC, I enjoy model binders. They take a huge amount of irrelevant infrastructure code out sight, out of code, and out of mind, making it easier to create and maintain.

Now, one of the most helpful custom binders that I use if the one that binds entity by id.

The basic idea is that if we have
  public ActionResult Action(Entity entity) {}
or in view model
  public Entity EntityProperty { get; set; }
we don't have to write any code - entity will be bound to data by the binder, and we get either object and no errors, or null and failed ModelState.

  public ActionResult Action(Entity entity)
  {
    if (!ModelState.IsValid) { return ... }
  }

Here we have model state errors for all failed entities (invalid IDs from page, not found in DB, etc), without any single line of code (except our one-for-all binder).

In the views, I have something like
  ${Html.HiddenFor(x => x.EntityProperty)}

I can't use .EditorFor(x => x.EntityProperty.Id) because I will get wrong name in POST, so how do I get id in the input value? There're two approaches:
1. Tweak view template or html helpers, so that, when entity (derived from BaseEntity, for example) is passed to HiddenFor, it uses .Id instead of .ToString()
2. Override Entity.ToString() to return .Id.ToString()

Now, even if we do Html.EditorFor(Model) - for entire model - we get proper IDs for entities, and we get them back on POST - without any additional code at all.

Sometimes, we want to bind by another property, not Id. E.g. in REST/urls we want product name as parameters, not ids - because it looks better in URLs. Hard? Not at all, we just apply a different binder:

  public ActionResult Action([ModelBinder(typeof(EntityNameBinder))] Entity entity) {}

where our EntityNameBinder is:
   public class EntityNameBinder : EntityBinder
   {
      public EntityNameBinder() : base("Name") { }
   }
- that is, we just pass property name to bind to. Internally binder uses repository to find entities (simplified):
  var rep = ServiceLocator.Current.GetInstance(typeof(IBaseRepository<>).MakeGenericType(entityType));

  var boundValue = rep.GetType().GetMethod("FindOne").Invoke(rep, new object[]{ new Dictionary<string, object>{{propertyName, valueFromView}} });

This method works even for lists, we just tweak our custom binder a bit to detect IList<Entity>/Entity. And so we can use this in view models:
  public IList<Entity> EntityListProperty { get; set; }
once again without any single line of additional code.

Another usefull aspect of this approach, is that controllers code is very clean - model in, model view out - and thus very easy to test.

And, last but not least, one should never bind to entities directly - because it is not safe (remote user can bind to non-desired public properties, etc). With this custom binder, this is completely eliminated - there's no way to fill entity properties with values from the page, period. The workflow is always to create view model (whose properties get values from the page) and then use it populate entity (using AutoMapper, for example).

Wednesday, February 16, 2011

Matryoshka

Opening remote ftp in VirtualBox guest though virtualbox shared folder that points to /home/user/.gvfs is how we all work today.

I mean, virtualization ├╝ber alles.

Friday, February 4, 2011

Moving to git

Yes, everybody did this already. And if you did not, hurry up! There's limited number of git repositories in the world, don't be late!

Git is a fantastic tool, and the only problem is that it looks too complex at first. But it is not, really, at least if you don't do fancy branching and merging within your 10 people scrum team. If you work alone (or in pair) it's much simpler and you can still benefit from it.

Here's why: whygitisbetterthanx.com/

Well, I just don't want to repeat what has been said so many times. But for me, it allows for much easier branching and merging. Often customers need a small fix to existing production version while I'm working on next sprint. git seems to have a lot of tools to make it easy - stash, easy branching, etc.

And it's fast.

Thursday, January 13, 2011

What matters

And frankly, ASP.NET MVC v1 is enough to go. No need for fancy stuff.

Because, what really matters is domain logic and code. ASP.NET MVC is just a thin framework, almost infrastructure. If it is >50% of your project, then your're doing it wrong. Move all the infrastructure out of the way (attributes, IoC, etc).