Tuesday, 18 December 2012

Bug in Typescript 0.8.1.1 when importing modules

After upgrading to Typescript 0.8.1.1 and compiling your project, if you happen to import modules like this:

  1. import ModuleA = module("MyModule");
  2. export class MyType{
  3.     Foo: ModuleA.MyOtherType;
  4. }


you might encounter this error:

public member 'XXXX' of exported class has or is using private type 'YYYY'

It looks like a bug in Typescript 0.8.1.1. After looking for an answer on the web, I found this discussion. Basically, the workaround is to make your imported module public by exporting them. Wait... what? Something like this:

  1. export import ModuleA = module("MyModule");

I guess that this will be fixed in a subsequent version.


    Saturday, 20 October 2012

    Asynchronously loading Javascript library in TypeScript

    What's the problem?

    In TypeScript, one way to use "native" Javascript libraries (like JQuery, Underscore, etc...) is to declare ambient variables in your code. The problem with these ambient variables is that you need to reference the corresponding Javascript files in your html when you want to use them. Since I am using AMD to load my modules, I would prefer using the same asynchronous mechanism to load existing Javascript libraries than having to reference all the libraries in my html. This post will describe the solution I found to this problem.


    Here is an example if you want to use the library Underscore.js in a Typescript file with the help of ambient variables.


    default.html:
    <head>
        <meta charset="utf-8" />
        <script src="underscore.js"></script>
        <script src="require.js"></script>
    </head>
    

    test.ts:

    /// <reference path='underscore.d.ts'/>
    declare var _: underscore;
    export class Test {
        executeTest() {
            _.each([1, 2, 3], function (num) { alert(num); });
        }
    }
    
    Reference: Underscore.d.ts.

    As you can see, I need to reference underscore.js in my html. If I had to use JQuery, the same thing would apply. But I would rather have something like this:

    default.html:
    <head>
        <meta charset="utf-8" />
        <script src="require.js"></script>
    </head>
    

    test.ts:

    import _ = module('underscore');
    export class Test {
        executeTest() {
            _.each([1, 2, 3], function (num) { alert(num); });
        }
    }
    

    In this example, you only need to include require.js in the html and import the module underscore. Obviously, that doesn't work because underscore is not a valid TypeScript module. 

    Here is the solution...


    The solution I found is not as clean as the previous example but it's as close as I can get. You can find the source on GitHub.


    Here is the file structure:


    \scripts\app.js
    \scripts\test.ts
    \scripts\underscoreLib.ts
    \scripts\libs\underscore.js
    \scripts\libs\require.js
    \default.htm
    

    And that's the code:

    default.html:
    
    
    <head>
        <meta charset="utf-8" />
        <script src="require.js" data-main='scripts/app'></script>
    </head>
    

    app.js:
    require.config({
        paths: {
            'underscoreLib': 'libs/underscore'
        },
        shim: {
            'underscoreLib': {
                exports: '_'
            }
        }
    });
    

    underscoreLib.ts
    export function each(obj: any, f: Function) { }
    

    test.ts
    import underscore = module('underscoreLib');
    var _:underscore = underscore;
    
    export class Test {
        executeTest() {
            _.each([1, 2, 3], function (num) { alert(num); });
        }
    }
    

    How it works?

    The first trick is to use shims with the Require.JS api. This basically lets us define the name of a module and associate it to the Javascript library we want to load. You can see in app.js that I define a module named 'underscoreLib' with the path = 'libs/underscore.js'. You also need to define what variable will be exported when the module will be loaded. In our case, that's the '_' of Underscore.JS, but for JQuery, that would be '$'.

    In pure Javascript, you would then use the define() method to load the underscoreLib module like like this:


    define(['underscoreLib'], function(_){
        _.each([1, 2, 3], function (num) { alert(num); });
    })
    

    The goal is to find a way in TypeScript to make the compiler generates a javascript file that follows this pattern. If you look at a generated Javascript file when you import a module in a TypeScript file, you will see that the require() method is used just like we want. So the other trick is to create a TypeScript file with the same name as the module name we used in the require shim. In our case, that would be underscoreLib. 

    If you look at the test.ts file, we import the module named 'underscoreLib'. Since we created the file named underscoreLin.ts the compiler knows that the module exist and it compile correctly. But then if you look at the Javascript, you have something like this:

    define(["require", "exports", 'underscoreLib'], function(require, exports, __underscore__) {
        var underscore = __underscore__;
    
        var _ = underscore;
        var Test = (function () {
            function Test() { }
            Test.prototype.executeTest = function () {
                _.each([1, 2, 3], function (num) { alert(num); });
            };
            return Test;
        })();
        exports.Test = Test;    
    })
    

    Exactly what we wanted. When Require.JS will try to load the underscoreLib module, it will use the shim config to find the Javascript file associated to it. When loaded, the 'underscore' variable will contains the '_' of the Underscore.JS library. To make it more natural to use, you can declare a variable '_' like this:


    var _:underscore = underscore;
    



    Note that if you want to use your Javascript library in a strong-typed manner, you must declare all methods in the TypeScript file corresponding to your module. In my example, I only declared the method 'each()' in the underscoreLib.ts file, but I would need to declare all the methods I want to use if I want my project to compile. If you don't care about strong-typing for your library, you can declare the '_' variable as a 'any' type like this:


    var _:any = underscore;

    In this case, you only need to export at least one method in the underscoreLib.ts, otherwise the compiler won't generate the module and the code won't compile.


    Et voilĂ ! I hope this can help other people. Let me know if you find a better way to do it.

    Friday, 18 November 2011

    Determine which NIC card will be used to route a specific IP address

    I tried to find an easy way in C# to determine which network interface card was going to be used if I had to connect to a specific address. This is done by the system with the help of the routing table.

    The only way I found was to use the unmanaged api of Windows. I am using the GetBestInterface() function from the iphlpapi.dll. This function returns the index that will be used to route the specified IP address. You must then use the GetAdaptersInfo() function from the same DLL to retrieve the network card info and determine which one corresponds to this index.

    This works well but note that you cannot use IPv6 address with the GetBestInterface(). On the other hand, the GetBestInterfaceEx() supports IPv6 but I was not able to make it work with C#.

    Error handling is missing and I only tested this on Vista 64 machine but it might be helpful for others:

    You can get the code from here: http://pastebin.com/u9159Ys8

    public class NetworkInterfaceHelper
    {
        private static readonly Dictionary<string, NetworkInterface> m_networkInterfaces;

        static NetworkInterfaceHelper()
        {
            m_networkInterfaces = NetworkInterface.GetAllNetworkInterfaces().ToDictionary(o => o.Id);
        }
         
        public static NetworkInterface GetBestInterface(IPAddress address)
        {
            byte[] byteArray1 = address.GetAddressBytes();
            uint ipaddr = BitConverter.ToUInt32(byteArray1, 0);
            uint interfaceIndex;
            int error = IPHelperInvoke.GetBestInterface(ipaddr, out interfaceIndex);

            if (error != 0)
            {
                throw new InvalidOperationException(string.Format("Error while calling GetBestInterface(). Error={0}", error));
            }
             
            var indexedIpAdapterInfo = AdapterInfo.IndexedIpAdapterInfos[interfaceIndex];

            return m_networkInterfaces[indexedIpAdapterInfo.AdapterName];
        }
    }
     
    public class AdapterInfo
    {
        public static IEnumerable<IPHelperInvoke.IP_ADAPTER_INFO> IpAdapterInfos { get; private set; }
        public static Dictionary<uint, IPHelperInvoke.IP_ADAPTER_INFO> IndexedIpAdapterInfos { get; private set; }
         
         
        static AdapterInfo()
        {
            IpAdapterInfos = RetrieveAdapters();
            IndexedIpAdapterInfos = IpAdapterInfos.ToDictionary(o => (uint)o.Index);
        }

        private static IEnumerable<IPHelperInvoke.IP_ADAPTER_INFO> RetrieveAdapters()
        {
            long structSize = Marshal.SizeOf(typeof(IPHelperInvoke.IP_ADAPTER_INFO));
            IntPtr pArray = Marshal.AllocHGlobal(new IntPtr(structSize));

            int ret = IPHelperInvoke.GetAdaptersInfo(pArray, ref structSize);
             
            IntPtr pEntry = pArray;
            if (ret == IPHelperInvoke.ERROR_BUFFER_OVERFLOW)
            {
                // Buffer was too small, reallocate the correct size for the buffer.
                pArray = Marshal.ReAllocHGlobal(pArray, new IntPtr(structSize));
                ret = IPHelperInvoke.GetAdaptersInfo(pArray, ref structSize);
            }

            List<IPHelperInvoke.IP_ADAPTER_INFO> result = new List<IPHelperInvoke.IP_ADAPTER_INFO>();

            if (ret == 0)
            {
                do
                {
                    // Retrieve the adapter info from the memory address
                    IPHelperInvoke.IP_ADAPTER_INFO entry = (IPHelperInvoke.IP_ADAPTER_INFO)Marshal.PtrToStructure(pEntry, typeof(IPHelperInvoke.IP_ADAPTER_INFO));

                    result.Add(entry);

                    // Get next adapter (if any)
                    pEntry = entry.Next;
                }
                while (pEntry != IntPtr.Zero);

                Marshal.FreeHGlobal(pArray);
            }
            else
            {
                Marshal.FreeHGlobal(pArray);
            }

            return result;
        }
    }

    public class IPHelperInvoke
    {
        public const int MAX_ADAPTER_ADDRESS_LENGTH = 8;

        public const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128;

        public const int MAX_ADAPTER_NAME_LENGTH = 256;

        public const int ERROR_BUFFER_OVERFLOW = 111;

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct IP_ADDRESS_STRING
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string Address;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct IP_ADDR_STRING
        {
            public IntPtr Next;
            public IP_ADDRESS_STRING IpAddress;
            public IP_ADDRESS_STRING IpMask;
            public Int32 Context;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct IP_ADAPTER_INFO
        {
            public IntPtr Next;
            public Int32 ComboIndex;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_NAME_LENGTH + 4)]
            public string AdapterName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_DESCRIPTION_LENGTH + 4)]
            public string AdapterDescription;
            public UInt32 AddressLength;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]
            public byte[] Address;
            public Int32 Index;
            public UInt32 Type;
            public UInt32 DhcpEnabled;
            public IntPtr CurrentIpAddress;
            public IP_ADDR_STRING IpAddressList;
            public IP_ADDR_STRING GatewayList;
            public IP_ADDR_STRING DhcpServer;
            public bool HaveWins;
            public IP_ADDR_STRING PrimaryWinsServer;
            public IP_ADDR_STRING SecondaryWinsServer;
            public Int32 LeaseObtained;
            public Int32 LeaseExpires;
        }

        [DllImport("iphlpapi.dll", CharSet = CharSet.Ansi)]
        public static extern int GetAdaptersInfo(IntPtr pAdapterInfo, ref Int64 pBufOutLen);

        [DllImport("iphlpapi.dll", SetLastError = true)]
        public static extern int GetBestInterface(UInt32 DestAddr, out UInt32 BestIfIndex);
    }


    Thanks PInvoke.net for the samples!


    Tuesday, 1 November 2011


    Struct to byte array example:


        class Program
        {
            internal struct Header
            {
                public int Size;
                public byte Checksum;
            }

            internal struct Packet
            {
                public Header Header;

                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
                public byte[] Data;
            }
       
            static void Main(string[] args)
            {
                // --------------------------
                // Init
                // --------------------------
                Packet packet = new Packet
                {
                    Header = new Header
                    {
                        Size = 8,
                        Checksum = 9
                    },
                    Data = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }
                };

                // --------------------------
                // Convert to bytes
                // --------------------------
                // Convert to "8 0 0 0 9 0 0 0 0 1 2 3 4 5 6 7"
                byte[] buffer = RawSerialize(packet);

                // --------------------------
                // Convert to object
                // --------------------------
                Packet newPacket = (Packet)RawDeserialize(buffer, 0, typeof(Packet));
            }

            public static object RawDeserialize(byte[] rawData, int position, Type anyType)
            {
                int rawsize = Marshal.SizeOf(anyType);
                if (rawsize > rawData.Length)
                    return null;

                IntPtr buffer = Marshal.AllocHGlobal(rawsize);
                Marshal.Copy(rawData, position, buffer, rawsize);
                object retobj = Marshal.PtrToStructure(buffer, anyType);
                Marshal.FreeHGlobal(buffer);
                return retobj;
            }

            public static byte[] RawSerialize(object anything)
            {
                int rawSize = Marshal.SizeOf(anything);
                IntPtr buffer = Marshal.AllocHGlobal(rawSize);
                Marshal.StructureToPtr(anything, buffer, false);
                byte[] rawDatas = new byte[rawSize];
                Marshal.Copy(buffer, rawDatas, 0, rawSize);
                Marshal.FreeHGlobal(buffer);
                return rawDatas;
            }
        }

    Wednesday, 14 September 2011

    DataContract Serialization: Deserializing objects pointing to existing instances

    When deserializing objects through DataContract, new objects will always be created. In some occasions you want to use existing instances instead of creating new ones. IObjectReference can be used to solve this problem.

    StackOverflow: C# DataContract Serialization, how to deserialize to already existing instance

    MSDN: IObjectReference Interface