Sunday, March 8, 2015

C# .NET Attributes Data (Beginner's Guide)

Introduction

This guide is all about how to add metadata to a C# program. This entry is aimed at the beginning C# developer who has experience with other programming languages. Metadata has a variety of uses- at the company I work for we're going to use it to provide more verbose information to consumers of some given code. It's a very .NET-y solution to a problem we've already solved in C++ using parsers. The advantage to metadata is that it's a solution that is already supported by the .NET framework.

Please note that all of the code that I'm writing is compiled using Mono. Mono is a cross-platform tool that can compile C# code into an intermediate form which can then be run.

The Initial Program

For the initial program I decided to use the "Hello World" program provided by the Mono project [1]. This had the duel purpose of testing out my Mono installation. The original HW program was kind of simple for the type of meta-information I wanted to provide. So it was modified. Here is the original code (once again, credit to the mono project):

using System;

public class HelloWorld
{
    static public void Main()
    {
        Console.WriteLine("Hello Mono World!");
    }
}

Let's change the program to instantiate a HelloWorld object and use a method to print a message out.

using System;

public class HelloWorld
{
    public void PrintMsg(String msg)
    {
        Console.WriteLine(msg);
    }

    static public void Main()
    {
        HelloWorld hw = new HelloWorld();
        hw.PrintMsg("Hello World!");
    }
}

Adding an Attribute Class

The example class now has a basic method (PrintMsg). I want to start inserting special meta data to the class and some of its functions. Let's start with a simple description field. To achieve this a custom Attribute class must be written. I'm going to call the attribute class "SomeMethod":

using System;

[AttributeUsage(AttributeTargets.All)]
public class SomeMethod : Attribute
{
    private string m_description;

    public string Description
    {
        get
        {
            return m_description;
        }
        set 
        {
            m_description = value;
        }
    }
}

This is a really simple attributes class that has one property called "Description". The Description property is implemented with the get/set methods. These are just shorthand ways to implement these basic accessors. It's also much more formal than most other languages.

The top line contains [AttributeUsage(AttributeTargets.All)] seems to help declare this class as an attribute that can be applied using metadata calls [2].

Applying the Custom Attribute

To apply the custom attribute, all that is necessary is to apply some metadata before the method and it automatically gets attached:

using System;

[AttributeUsage(AttributeTargets.All)]
public class SomeMethod : Attribute
{
    private string m_description;

    public string Description
    {
        get
        {
            return m_description;
        }
        set 
        {
            m_description = value;
        }
    }
}


public class HelloWorld
{
    [SomeMethod(Description="This is a description of PrintMsg")]
    public void PrintMsg(String msg)
    {
        Console.WriteLine(msg);
    }

    static public void Main()
    {
        HelloWorld hw = new HelloWorld();
        hw.PrintMsg("Hello World!");
    }
}

I put the introduced attribute in bold.

Using Reflection to Query Attributes

The only step left is now querying the attributes placed on members/methods. This is pretty simple using a language feature called Reflection. So I modified the main part of the program to contain the following lines:

public class HelloWorld
{
    [SomeMethod(Description="This is a description of PrintMsg")]
    public void PrintMsg(String msg)
    {
        Console.WriteLine(msg);
    }

    static public void Main()
    {
        HelloWorld hw = new HelloWorld();
        hw.PrintMsg("Hello World!");

        Type hwInfo = typeof(HelloWorld);

        System.Reflection.MemberInfo[] memberInfo = hwInfo.GetMembers();
        foreach(System.Reflection.MemberInfo mInfo in memberInfo)
        {
            Console.WriteLine(mInfo.ToString());
       
            object[] attributes = mInfo.GetCustomAttributes(true);
            Console.WriteLine("\tNumber of attributes: " + attributes.Length);
            for(int i=0; i<attributes.Length; i++)
            {
                System.Console.WriteLine("\t\t" + attributes[i]);
            }
        }
    }
}

This program is now modified to print out all of the methods inside of HelloWorld and whether or not there were custom attributes applied. The point of this step is to partially explore what can be queried with Reflection.

Learning Note: When I ran this program in Mono it was observed that my one simple class had more than one method. Being a veteran C++ developer I am familiar with methods (constructors, assignment operators, etc) being added to classes. It appears as though C# also does something similar adding: 

  • Boolean Equals(System.String)
  • Int32 GetHashCode()
  • System.Type GetType()
  • System.String ToString()
  • Void .ctor()
I must admit that these methods all look really useful! As a C# beginner I think another entry might be useful to describe what these methods do. 


If we want to detect when a method has an attribute, it's as simple as:

public class HelloWorld
{
    [SomeMethod(Description="This is a description of PrintMsg")]
    public void PrintMsg(String msg)
    {
        Console.WriteLine(msg);
    }

    static public void Main()
    {
        HelloWorld hw = new HelloWorld();
        hw.PrintMsg("Hello World!");

        Type hwInfo = typeof(HelloWorld);

        System.Reflection.MemberInfo[] memberInfo = hwInfo.GetMembers();
        foreach(System.Reflection.MemberInfo mInfo in memberInfo)
        {
            Console.WriteLine(mInfo.ToString());

            SomeMethod sm = 
               (SomeMethod) Attribute.GetCustomAttribute( mInfo
                                                        , typeof(SomeMethod));
            if (sm != null)
            {
                Console.WriteLine("\tHAS IT!\n");
            }
        }
    }
}

This program will now print out a message when the SomeMethod is obtained!

Conclusion

I really hate to admit this- C# looks awesome! I really enjoyed using Mono to run these examples. I know the examples were simple but I'm impressed with how the language defines its own custom attributes. In my next entry on this feature I'll explore how to add lists of things to attributes.


REFERENCES

[1] - http://www.mono-project.com/docs/getting-started/mono-basics/

[2] - https://msdn.microsoft.com/en-us/library/aa288454%28v=vs.71%29.aspx

[3] -https://msdn.microsoft.com/en-us/library/aa288454%28v=vs.71%29.aspx#vcwlkattributestutorialanchor3


Sunday, March 1, 2015

Where to find Qt Configure Flags

Introduction

It's Sunday afternoon and I'm about to re-setup a development virtual machine. In the creation of it I'm going to be building Qt5 from source on Linux. Building from source can be troublesome at times because it's hard to find good information about the configure "script". This small entry is about where to find information (from source code) about Qt's configure "script".

If I do a quick google search with "Qt configure documentation", the first good link I get is for Qt4:

http://qt-project.org/doc/qt-4.8/configure-options.html

Not bad. The link below it is for Qt 5.4:

http://doc.qt.io/qt-5/configure-options.html

In the tradition of ever obtrusive documentation, it's very wordy and hard to find what you are looking for. In my opinion the documentation style for Qt5 is inferior to Qt4 (opinions are subject to change).

This entry is all about the actual mechanism behind the configure "script". I am putting script in quotation marks because it's not actually a script- it's an executable. The first step after pulling Qt down from source is to run "configure" in the root directory. Obviously if using Visual Studio you must have run this from the VS Command Prompt.

QT/configure [.bat]

There are two scripts in two languages named "configure" in the root directory. The regular old configure script is a shell script that simply executes qtbase/configure. The configure.bat does the same in its own way executing qtbase/configure.bat.

QT/qtbase/configure.bat

This script begins the "bootstrapping configure". Essentially it runs a perl script called syncqt.pl and then tries to build the configure tool in QT/tools/configure. The configure executable tool takes the place of the QT/qtbase/configure. When I built Qt 5.3 it looks as if this tool was never built- looks as if this is a Windows only step.

QT/qtbase/configure

This is a shell script that does the actual setup for the build. When using Visual Studio, this won't be utilized. Instead the configure application listed above is used. The reason why it exists this way is probably due to batch files being rotten but I could be wrong.

Where are the build options for configure?

In conclusion, to find the base options for the configure step in Qt the developer could look in QT/qtbase/configure (which is the script used for Linux) OR look qt QT/qtbase/tools/configureapp.cpp in the method Configure::parseCmdLine().

 - Visual Studio     - SOURCE : $QTDIR/qtbase/tools/configure/configureapp.cpp
   - TYPE   : Binary Application
   - METHOD : Configure::parseCmdLine()
 - Linux (Other)
   - SOURCE : $QTDIR/qtbase/configure
   - TYPE   : Shell Script
   - METHOD : Line 828? Look for "parse command line arguments"

Using the source code the developer can get definitive information about the configure arguments that can be passed into building Qt.