Building Applications that Can Talk

هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

Overview

Stephen Hawking is one of the most famous people using speech synthesis to communicate

Stephen Hawking is one of the most famous people using speech synthesis to communicate

In this article we are going to explore the Speech API library that’s part of the TTS SDK that helps you reading text and speaking it. We’re going to see how to do it programmatically using C# and VB.NET and how to make use of LINQ to make it more interesting. The last part of this article talks about…… won’t tell you more, let’s see!

Introduction

The Speech API library that we are going to use today is represented by the file sapi.dll which’s located in %windir%System32SpeechCommon. This library is not part of the .NET BCL and it’s not even a .NET library, so we’ll use Interoperability to communicate with it (don’t worry, using Visual Studio it’s just a matter of adding a reference to the application.)

Implementation

In this example, we are going to create a Console application that reads text from the user and speaks it. To complete this example, follow these steps:

As an example, we’ll create a simple application that reads user inputs and speaks it. Follow these steps:

  1. Create a new Console application.
  2. Add a reference to the Microsoft Speech Object Library (see figure 1.)

    Figure 1 - Adding Reference to SpeechLib Library

    Figure 1 - Adding Reference to SpeechLib Library

  3. Write the following code and run your application:
// C#

using SpeechLib;

static void Main()
{
    Console.WriteLine("Enter the text to read:");
    string txt = Console.ReadLine();
    Speak(txt);
}

static void Speak(string text)
{
    SpVoice voice = new SpVoiceClass();
    voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault);
}
' VB.NET

Imports SpeechLib

Sub Main()
    Console.WriteLine("Enter the text to read:")
    Dim txt As String = Console.ReadLine()
    Speak(txt)
End Sub

Sub Speak(ByVal text As String)
    Dim voice As New SpVoiceClass()
    voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault)
End Sub

If you are using Visual Studio 2010 and .NET 4.0 and the application failed to run because of Interop problems, try disabling Interop Type Embedding feature from the properties on the reference SpeechLib.dll.

Building Talking Strings

Next, we’ll make small modifications to the code above to provide an easy way to speak a given System.String. We’ll make use of the Extension Methods feature of LINQ to add the Speak() method created earlier to the System.String. Try the following code:

// C#

using SpeechLib;

static void Main()
{
    Console.WriteLine("Enter the text to read:");
    string txt = Console.ReadLine();
    txt.Speak();
}

static void Speak(this string text)
{
    SpVoice voice = new SpVoiceClass();
    voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault);
}
' VB.NET

Imports SpeechLib
Imports System.Runtime.CompilerServices

Sub Main()
    Console.WriteLine("Enter the text to read:")
    Dim txt As String = Console.ReadLine()
    txt.Speak()
End Sub

<Extension()> _
Sub Speak(ByVal text As String)
    Dim voice As New SpVoiceClass()
    voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault)
End Sub

I Love YOU ♥

Let’s make it more interesting. We are going to code a VBScript file that says “I Love YOU” when you call it. To complete this example, these steps:

  1. Open Notepad.
  2. Write the following code:
    CreateObject("SAPI.SpVoice").Speak "I love YOU!"

    Of course, CreateObject() is used to create a new instance of an object resides in a given library. SAPI is the name of the Speech API library stored in Windows Registry. SpVoice is the class name.

  3. Save the file as ‘love.vbs’ (you can use any name you like, just preserve the vbs extension.)
  4. Now open the file and listen, who is telling that he loves you!

Microsoft Speech API has many voices; two of them are Microsoft Sam (male), the default for Windows XP and Windows 2000, and Microsoft Ann (female), the default for Windows Vista and Windows 7. Read more about Microsoft TTS voices here.

Thanks to our friend, Mohamed Gafar, for providing the VBScript.

.NET Interoperability at a Glance 3 – Unmanaged Code Interoperation

هذه المقالة متوفرة باللغة العربية أيضا، اقرأها هنا.

See more Interoperability examples here.

Contents

Contents of this article:

  • Contents
  • Read also
  • Overview
  • Unmanaged Code Interop
  • Interop with Native Libraries
  • Interop with COM Components
  • Interop with ActiveX Controls
  • Summary
  • Where to go next

Read also

More from this series:

Overview

This is the last article in this series, it talks about unmanaged code interoperation; that’s, interop between .NET code and other code from other technologies (like Windows API, native libraries, COM, ActiveX, etc.)

Be prepared!

Introduction

Managed code interop wasn’t so interesting, so it’s the time for some fun. You might want to call some Win32 API functions, or it might be interesting if you make use of old, but useful, COM components. Let’s start!

Unmanaged Code Interop

Managed code interoperation isn’t so interesting, but this is. Unmanaged interoperation is not easy as the managed interop, and it’s also much difficult and much harder to implement. In unmanaged code interoperation, the first system is the .NET code; the other system might be any other technology including Win32 API, COM, ActiveX, etc. Simply, unmanaged interop can be seen in three major forms:

  1. Interoperation with Native Libraries.
  2. Interoperation with COM components.
  3. Interoperation with ActiveX.

Interop with Native Libraries

This is the most famous form of .NET interop with unmanaged code. We usually call this technique, Platform Invocation, or simply PInvoke. Platform Invocation or PInvoke refers to the technique used to call functions of native unmanaged libraries such as the Windows API.

To PInvoke a function, you must declare it in your .NET code. That declaration is called the Managed Signature. To complete the managed signature, you need to know the following information about the function:

  1. The library file which the function resides in.
  2. Function name.
  3. Return type of the function.
  4. Input parameters.
  5. Other relevant information such as encoding.

Here comes a question, how could we handle types in unmanaged code that aren’t available in .NET (e.g. BOOL, LPCTSTR, etc.)?

The solution is in Marshaling. Marshaling is the process of converting unmanaged types into managed and vice versa (see figure 1.) That conversion can be done in many ways based on the type to be converted. For example, BOOL can simply be converted to System.Boolean, and LPCTSTR can be converted to System.String, System.Text.StringBuilder, or even System.Char[]. Compound types (like structures and unions) are usually don’t have counterparts in .NET code and thus you need to create them manually. Read our book about marshaling here.

Figure 1 - The Marshaling Process
Figure 1 – The Marshaling Process

To understand P/Invoke very well, we’ll take an example. The following code switches between mouse button functions, making the right button acts as the primary key, while making the left button acts as the secondary key.

In this code, we’ll use the SwapMouseButtons() function of the Win32 API which resides in user32.dll library and has the following declaration:

BOOL SwapMouseButton(
    BOOL fSwap
    );

Of course, the first thing is to create the managed signature (the PInvoke method) of the function in .NET:

// C#
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern bool SwapMouseButton(bool fSwap);
' VB.NET
Declare Auto Function SwapMouseButton Lib "user32.dll" _
    (ByVal fSwap As Boolean) As Boolean

Then we can call it:

// C#

public void MakeRightButtonPrimary()
{
    SwapMouseButton(true);
}

public void MakeLeftButtonPrimary()
{
    SwapMouseButton(false);
}
' VB.NET

Public Sub MakeRightButtonPrimary()
    SwapMouseButton(True)
End Sub

Public Sub MakeLeftButtonPrimary()
    SwapMouseButton(False)
End Sub

Interop with COM Components

The other form of unmanaged interoperation is the COM Interop. COM Interop is very large and much harder than P/Invoke and it has many ways to implement. For the sake of our discussion (this is just a sneak look at the technique,) we’ll take a very simple example.

COM Interop includes all COM-related technologies such as OLE, COM+, ActiveX, etc.

Of course, you can’t talk directly to unmanaged code. As you’ve seen in Platform Invocation, you have to declare your functions and types in your .NET code. How can you do this? Actually, Visual Studio helps you almost with everything so that you simply to include a COM-component in your .NET application, you go to the COM tab of the Add Reference dialog (figure 2) and select the COM component that you wish to add to your project, and you’re ready to use it!

Figure 2 - Adding Reference to SpeechLib Library
Figure 2 – Adding Reference to SpeechLib Library

When you add a COM-component to your .NET application, Visual Studio automatically declares all functions and types in that library for you. How? It creates a Proxy library (i.e. assembly) that contains the managed signatures of the unmanaged types and functions of the COM component and adds it to your .NET application.

The proxy acts as an intermediary layer between your .NET assembly and the COM-component. Therefore, your code actually calls the managed signatures in the proxy library that forwards your calls to the COM-component and returns back the results.

Keep in mind that proxy libraries also called Primary Interop Assemblies (PIAs) and Runtime Callable Wrappers (RCWs.)

Best mentioning that Visual Studio 2010 (or technically, .NET 4.0) has lots of improved features for interop. For example, now you don’t have to ship a proxy/PIA/RCW assembly along with your executable since the information in this assembly can now be embedded into your executable; this is what called, Interop Type Embedding.

Of course, you can create your managed signatures manually, however, it’s not recommended especially if you don’t have enough knowledge of the underlying technology and the marshaling of functions and types (you know what’s being said about COM!)

As an example, we’ll create a simple application that reads user inputs and speaks it. Follow these steps:

  1. Create a new Console application.
  2. Add a reference to the Microsoft Speech Object Library (see figure 2.)
  3. Write the following code and run your application:
// C#

using SpeechLib;

static void Main()
{
    Console.WriteLine("Enter the text to read:");
    string txt = Console.ReadLine();
    Speak(txt);
}

static void Speak(string text)
{
    SpVoice voice = new SpVoiceClass();
    voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault);
}
' VB.NET

Imports SpeechLib

Sub Main()
    Console.WriteLine("Enter the text to read:")
    Dim txt As String = Console.ReadLine()
    Speak(txt)
End Sub

Sub Speak(ByVal text As String)
    Dim voice As New SpVoiceClass()
    voice.Speak(text, SpeechVoiceSpeakFlags.SVSFDefault)
End Sub

If you are using Visual Studio 2010 and .NET 4.0 and the application failed to run because of Interop problems, try disabling Interop Type Embedding feature from the properties on the reference SpeechLib.dll.

Interop with ActiveX Controls

ActiveX is no more than a COM component that has an interface. Therefore, nearly all what we have said about COM components in the last section can be applied here except the way we add ActiveX components to our .NET applications.

To add an ActiveX control to your .NET application, you can right-click the Toolbox, select Choose Toolbox Items, switch to the COM Components tab and select the controls that you wish to use in your application (see figure 3.)

Figure 3 - Adding WMP Control to the Toolbox
Figure 3 – Adding WMP Control to the Toolbox

Another way is to use the aximp.exe tool provided by the .NET Framework (located in Program FilesMicrosoft SDKsWindowsv7.0Abin) to create the proxy assembly for the ActiveX component:

aximp.exe "C:WindowsSystem32wmp.dll"

Not surprisingly, you can create the proxy using the way for COM components discussed in the previous section, however, you won’t see any control that can be added to your form! That way creates control class wrappers for unmanaged ActiveX controls in that component.

Summary

So, unmanaged code interoperation comes in two forms: 1) PInvoke: interop with native libraries including the Windows API 2) COM-interop which includes all COM-related technologies like COM+, OLE, and ActiveX.

To PInvoke a method, you must declare it in your .NET code. The declaration must include 1) the library which the function resides in 2) the return type of the function 3) function arguments.

COM-interop also need function and type declaration and that’s usually done for you by the Visual Studio which creates a proxy (also called RCW and PIA) assembly that contains managed definitions of the unmanaged functions and types and adds it to your project.

Where to go next

Read more about Interoperability here.

More from this series:

.NET Interoperability at a Glance 2 – Managed Code Interoperation

هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

See more Interoperability examples here.

Contents

Contents of this article:

  • Contents
  • Read also
  • Overview
  • Introduction
  • Forms of Interop
  • Managed Code Interop
  • Summary
  • Where to go next

Read also

More from this series:

Overview

In the previous article, you learnt what interoperability is and how it relates to the .NET Framework. In this article, we’re going to talk about the first form of interoperability, the Managed Code Interop. In the next article, we’ll talk about the other forms.

Introduction

So, to understand Interoperation well in the .NET Framework, you must see it in action. In this article, we’ll talk about the first form of .NET interoperability and see how to implement it using the available tools.

Just a reminder, Interoperability is the process of communication between two separate systems. In .NET Interop, the first system is always the .NET Framework; the other system might be any other technology.

Forms of Interop

Interoperability in .NET Framework has two forms:

  • Managed Code Interoperability
  • Unmanaged Code Interoperability

Next, we have a short discussion of each of the forms.

Managed Code Interop

This was one of the main goals of .NET Framework. Managed Code Interoperability means that you can easily communicate with any other .NET assembly no matter what language used to build that assembly.

Not surprisingly, because of the nature of .NET Framework and its runtime engine (the CLR,) .NET code supposed to be called Managed Code, while any other code is  unmanaged.

To see this in action, let’s try this:

  1. Create a new Console application in the language you like (C#/VB.NET.)
  2. Add a new Class Library project to the solution and choose another language other than the one used in the first project.
  3. In the Class Library project, add the following code (choose the suitable project):
    // C#
    
    public static class Hello
    {
        public static string SayHello(string name)
        {
            return "Hello, " + name;
        }
    }
    ' VB.NET
    
    Public Module Hello
        Public Function SayHello(ByVal name As String) As String
            Return "Hello, " & name
        End Function
    End Module
  4. Now, go back to the Console application. Our goal is to call the function we have added to the other project. To do this, you must first add a reference to the library in the first project. Right-click the Console project in Solution Explorer and choose Add Reference to open the Add Reference dialog (figure 1.) Go to the Projects tab and select the class library project to add it.

    Figure 1 - Add Reference to a friend project

    Figure 1 - Add Reference to a friend project

  5. Now you can add the following code to the Console application to call the SayHello() function of the class library.
    // C#
    
    static void Main()
    {
        Console.WriteLine(ClassLibrary1.Hello.SayHello("Mohammad Elsheimy"));
    }
    ' VB.NET
    
    Sub Main()
        Console.WriteLine(ClassLibrary1.Hello.SayHello("Mohammad Elsheimy"))
    End Sub

How this happened? How could we use the VB.NET module in C# which is not available there (or the C#’s static class in VB which is not available there too)?

Not just that, but you can inherit C# classes from VB.NET (and vice versa) and do all you like as if both were created using the same language. The secret behind this is the Common Intermediate Language (CIL.)

When you compile your project, the compiler actually doesn’t convert your C#/VB.NET code to instructions in the Machine language. Rather, it converts your code to another language of the .NET Framework, which is the Common Intermediate Language. The Common Intermediate Language, or simply CIL, is the main language of .NET Framework which inherits all the functionalities of the framework, and which all other .NET languages when compiled are converted to it.

So, the CIL fits as a middle layer between your .NET language and the machine language. When you compile your project, the compiler converts your code to CIL statements and emits them in assembly file. In runtime, the compiler reads the CIL from the assembly and converts them to machine-readable statements.

How CIL helps in interoperation? The communication between .NET assemblies is now done through the CIL of the assemblies. Therefore, you don’t need to be aware of structures and statements that are not available in your language since every statement for any .NET language has a counterpart in IL. For example, both the C# static class and VB.NET module convert to CIL static abstract class (see figure 2.)

Figure 2 - CIL and other .NET languages

Figure 2 - CIL and other .NET languages

Managed Interop is not restricted to C# and VB.NET only; it’s about all languages run inside the CLR (i.e. based on .NET Framework.)

If we have a sneak look at the CIL generated from the Hello class which is nearly the same from both VB.NET and C#, we would see the following code:

.class public abstract auto ansi sealed beforefieldinit ClassLibrary1.Hello
       extends [mscorlib]System.Object
{

    .method public hidebysig static string  SayHello(string name) cil managed
    {
      // Code size       12 (0xc)
      .maxstack  8
      IL_0000:  ldstr      "Hello, "
      IL_0005:  ldarg.0
      IL_0006:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
      IL_000b:  ret
    } // end of method Hello::SayHello

} // end of class ClassLibrary1.Hello

On the other hand, this is the code generated from the Main function (which is also the same from VB.NET/C#):

.class public abstract auto ansi sealed beforefieldinit ConsoleApplication1.Program
       extends [mscorlib]System.Object
{

    .method private hidebysig static void  Main() cil managed
    {
      .entrypoint
      .maxstack  8
      IL_0000:  ldstr      "Mohammad Elsheimy"
      IL_0005:  call       string [ClassLibrary1]ClassLibrary1.Hello::SayHello(string)
      IL_000a:  call       void [mscorlib]System.Console::WriteLine(string)
      IL_000f:  ret
    } // end of method Program::Main

} // end of class ConsoleApplication1.Program

You can use the ILDasm.exe tool to get the CIL code of an assembly. This tool is located in Program FilesMicrosoft SDKsWindows<version>bin.

Here comes a question, is there CIL developers? Could we write the CIL directly and build it into .NET assembly? Why we can’t find much (if not any) CIL developers? You can extract the answer from the CIL code itself. As you see, CIL is not so friendly and its statements are not so clear. Plus, if we could use common languages to generate the CIL, we we’d like to program in CIL directly? So it’s better to leave the CIL for the compiler.

Now, let’s see the other form of .NET interoperation, Unmanaged Code Interoperability.

Summary

So, the secret of Managed Code Interoperation falls in the Common Intermediate Language or CIL. When you compile your code, the compiler converts your C#/VB.NET (or any other .NET language) to CIL instructions and saves them in the assembly, and that’s the secret. The linking between .NET assemblies of different languages relies on the fact that the linking is actually done between CILs of the assemblies. The assembly code doesn’t (usually) have any clue about the language used to develop it. In the runtime, the compiler reads those instructions and converts them to machine instructions and execute them.

Next, we’ll talk about the other form of .NET Interoperation, it’s the interoperation with unmanaged code.

Where to go next

Read more about Interoperability here.

More from this series:

.NET Interoperability at a Glance 1 – Introduction

هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

See more Interoperability examples here.

Contents

Contents of this article:

  • Contents
  • Read also
  • Overview
  • Introduction
  • Summary
  • Where to go next

Read also

More from this series:

Overview

.Net Framework Logo
Image via Wikipedia

In this article and the few following it, we’ll try to take a tour in Interoperability in .NET Framework.

In this lesson, we’ll start by an introduction to the concept of Interoperability. In the next few lessons, we’ll have a look at Interoperability and how it fits into the .NET Framework and other technologies.

Since Interoperability is a very huge topic and cannot be covered in just a few articles, we’ll concentrate on Interoperability in .NET Framework (not any other technologies) and summarize its uses.

Here we go!

Introduction

Let’s get hands on the concept of Interoperability and it’s relation to the .NET Framework.

Concept

Interoperability (reduced to Interop) is the ability of two diverse systems or different systems to communicate (i.e. inter-operate) with each other. When I say ‘two systems’ I assume that the first one is always the .NET Framework, since we are interested in .NET and also the interoperability is a very huge topic and cannot be summarized in just a few articles. The other system might be any other software, component, or service based on any technology other than the .NET Framework. For example, we could interoperate with Win32 API, MFC applications, COM/ActiveX components, and so on.

So we have two different systems, the first is the .NET Framework, while the other is any other technology. Our goal is to communicate with that stranger; that’s the main goal of Interoperability in .NET Framework.

Goals and Benefits

Here comes a question (or a few questions!), why do I need interoperation? Why I do need to communicate with other systems at all? If I need specific features, couldn’t I just use existing functionalities of .NET Framework to accomplish my tasks? I can even redevelop them!

We can summarize the answer of those questions in a few points:

  • First, in many cases, you can’t redevelop those components because the functionalities they offer is either very difficult (sometimes impossible) or maybe you don’t sufficient knowledge to redevelop them! Unless if you are very brilliant and have enough knowledge of the Assembly language, you can develop your API that would replace current system API, and then you’ll have also to interoperate with your API to be able to call it from your .NET Framework application.
  • If you’re not convinced yet, this is should be for you. You might be not having enough time to redevelop the component that may take a very long time and effort to complete. Imagine how much time would take to code, debug, and test your component. Plus, you can rely on existing components and trust them, many bugs can appear in your code from time to time and you’ll have to fix them all!
  • Other 3rd party component might not exist, or maybe the company you work for require you to use such those components.
  • You don’t need to reinvent the wheel, do you?

So, including Interop code in your .NET projects is sometimes inevitable (especially when working with Windows API) that you definitely can’t keep yourself away from them.

Summary

So you have now basic understanding of what Interoperability means. As a reminder, Interoperability is the process of two diverse systems communicate with each other. For us, the first system is the .NET Framework. The other system is any other technology (Windows API, MFC, COM/ActiveX, etc.)

You can’t live without Interop, actually you did some interoperation in your work (you may be actually do that every day.)

Now you are ready to take a look at how Interop fits in .NET Framework.

Where to go next

Read more about Interoperability here.

More from this series:

Understanding Value Types and Reference Types

هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

Contents

Contents of this article:

  • Contents
  • Introduction
  • Passing Mechanism
  • The Two Genres
  • Value Types
  • Reference Types
  • Boxing and Unboxing
    • Manual Boxing
    • Manual Unboxing
    • Automatic Boxing
    • Automatic Unboxing
  • Summary

Introduction

Today, we’ll have a brief discussion of value types and reference types in .NET framework and how their behavior change while used or passed to functions. We’ll talk about the passing mechanism, the two genres of .NET types, the scope, and the conversion routines between the two genres.

Passing Mechanism

When you pass an object to a function, this object can be passed either by value or by reference.

To pass an object by value means that a copy of the object is passed to the function not the object itself so changes to the object inside the function won’t affect your original copy.

On the other hand, passing an object by reference means passing that object itself so changes to the object inside that function is reflected on your original copy.

Consider the following example. Although the function changed the value of i, the change didn’t affect the original variable that’s because the variable is passed by value.

// C#

static void Main()
{
    int i = 10;
    int j = i;

    j = 5;

    // you expect '5'
    Console.WriteLine(i);
    // but i is still 10 !!

    // Now you try another way

    Sqr(i);

    // you expect '100'
    Console.WriteLine(i);
    // but i is still 10 !!!
}

static void Sqr(int i)
{
    i *= i;
}
' VB.NET

Sub Main()
    Dim i As Integer = 10
    Dim j As Integer = i

    j = 5

    ' you expect '5'
    Console.WriteLine(i)
    ' but i is still 10 !!!

    ' now you try another way

    Sqr(i)

    ' you expect '100'
    Console.WriteLine(i)
    ' but i is still 10 !!!
End Sub

Sub Sqr(ByVal i As Integer)
    i = i * i
End Sub

Now, let’s try something else. The following example passes i by reference.

// C#

static void Main()
{
    int i = 10;

    Sqr(ref i);

    // you expect '100'
    Console.WriteLine(i);

    // you are right!
}

static void Sqr(ref int i)
{
    i *= i;
}
' VB.NET

Sub Main()
    Dim i As Integer = 10

    Sqr(i)

    ' you expect '100'
    Console.WriteLine(i)

    ' you are right!
End Sub

Sub Sqr(ByRef i As Integer)
    i = i * i
End Sub

Notice how the ref keyword in C# (ByRef in VB.NET) changed the overall behavior. Now, i itself is passed to our function, so the changes made in the function affected the original variable (both are the same.)

The Two Genres

Talking about passing object by value or by reference leads up to talk about the two major genres of types in .NET Framework:

  • Value Types
  • Reference Types

Value Types

Value types are those normally passed by value unless you explicitly specify the ref keyword (or ByVal in VB.NET) to override the default behavior and pass the object by reference.

Value types in .NET are those inherit -directly or indirectly- from System.ValueType including all structures, enumerations, and primitives (integers, floats, etc.)

The previous examples use an integer value that’s absolutely a value-type.

Value types are stored on the first section of the memory, the stack. Thus, they are removed from memory as soon as their scope ends. The scope marks the beginning and the end of object’s life (object is considered alive at the time you declare it.) See the following code the marks scopes inside a class.

// C#

class ClassScope
{
    // Scope 1

    void Method1()
    {
        // Scope 1.1

        {
            // Scope 1.1.1
            {
                // Scope 1.1.1.1
            }

            {
                // Scope 1.1.1.2
            }
        }
    }

    void Method2()
    {
        // Scope 1.2

        if (true)
        {
            // Scope 1.2.1

            while (true)
            {
                // Scope 1.2.1.1
            }
        }
    }
}
' VB.NET

Class ClassScope
    ' Scope 1

    Sub Method1()
        ' Scope 1.1
    End Sub

    Sub Method2()
        ' Scope 1.2

        If True Then
            ' Scope 1.2.1

            Do While True
                ' Scope 1.2.1.1
            Loop
        End If
    End Sub
End Class

Reference Types

Reference types are those normally passed by reference and never can be passed by value. Reference types include all objects other than value types, we mean all other classes inherit from System.Object -directly or indirectly- and don’t inherit from System.ValueType.

Reference types are stored in the other version of the memory, the heap, and you can’t determine when the object is removed from memory since the heap is fully managed by the memory manager of .NET, the GC (Garbage Collector.)

Now, let’s see the difference between value types and reference types in action. The following example instantiates two objects, one is a structure (value type) and the other is a class (reference types.) After that, both objects are passed to two functions, both try to change the contents of the objects. The changes of the function affect the reference type outside, while the other value type object outside the function doesn’t get affected.

// C#

static void Main()
{
    ValStruct valObj = new ValStruct();
    RefClass refObj = new RefClass();

    valObj.x = 4;
    valObj.y = 4;
    refObj.x = 4;
    refObj.y = 4;

    MultipleStruct(valObj);
    MultipleClass(refObj);

    Console.WriteLine("Struct:tx = {0},ty = {1}",
        valObj.x, valObj.y);

    Console.WriteLine("Class:tx = {0},ty = {1}",
        refObj.x, refObj.y);

    // Results
    // Struct:  x = 4,  y = 4
    // Class:   x = 8,  y = 8
}

static void MultipleStruct(ValStruct obj)
{
    obj.x *= 2;
    obj.y *= 2;
}

static void MultipleClass(RefClass obj)
{
    obj.x *= 2;
    obj.y *= 2;
}

struct ValStruct
{
    public int x;
    public int y;
}

class RefClass
{
    public int x;
    public int y;
}
' VB.NET

Sub Main()

    Dim valObj As New ValStruct()
    Dim refObj As New RefClass()

    valObj.x = 4
    valObj.y = 4
    refObj.x = 4
    refObj.y = 4

    MultipleStruct(valObj)
    MultipleClass(refObj)

    Console.WriteLine("Struct:tx = {0},ty = {1}", _
            valObj.x, valObj.y)

    Console.WriteLine("Class:tx = {0},ty = {1}", _
            refObj.x, refObj.y)

    ' Results
    ' Struct:  x = 4,  y = 4
    ' Class:   x = 8,  y = 8
End Sub

Sub MultipleStruct(ByVal obj As ValStruct)
    obj.x *= 2
    obj.y *= 2
End Sub

Sub MultipleClass(ByVal obj As RefClass)
    obj.x *= 2
    obj.y *= 2
End Sub

Structure ValStruct
    Public x As Integer
    Public y As Integer
End Structure

Class RefClass
    Public x As Integer
    Public y As Integer
End Class

A little yet very important note: When comparing objects with the double equal signs (or the single sign in VB.NET,) objects are being compared internally using the System.Object.Equals() function. This function returns True if both value objects have the same value or both reference objects refer to the same object (doesn’t matter if both have the same value and are different objects.) Conversely, using the not equals operator (!= in C# and <> in VB.NET) uses the same comparison function, however, it reverses its return value (True becomes False and vice versa.)

Boxing and Unboxing

Boxing is the process of converting a value type into reference type. Unboxing on the other hand is the process of converting that boxed value type to its original state. Boxing and unboxing can be done manually (by you) or automatically (by the runtime.) Let’s see this in action.

Manual Boxing

Consider the following code:

    // C#
    byte num = 25;
    object numObj = num;
    ' VB.NET
    Dim num As Byte = 25
    Dim numObj As Object = num

The last code simply converted a value type (the byte variable) into reference type by encapsulating it into a System.Object variable. Does that really involve that passing the System.Object would be done by reference? Absolutely! (Check it yourself!)

Manual Unboxing

Now you have a boxed byte, how can you retrieve it later, i.e., restore it back to be a value type? Consider the following code:

    // C#
    // Boxing
    byte num = 25;
    object numObj = num;
    // Unboxing
    byte anotherNum = (byte)numObj;
    'VB.NET
    'Boxing
    Dim num As Byte = 25
    Dim numObj As Object = num
    'Unboxing
    Dim anotherNum As Byte = CByte(numObj)

Beware not to try to convert a boxed value to another type not its original type.

Automatic Boxing

Boxing can be done automatically by the runtime if you tried to pass that value type to a function that accepts a System.Object not that value type.

// C#
static void Main()
{
    byte num = 25;

    // Automatic Boxing
    Foo (num);
}

static void Foo(object obj)
{
    Console.WriteLine(obj.GetType());
    Console.WriteLine(obj.ToString());
}
' VB.NET
Sub Main()
    Dim num As Byte = 25

    'Automatic Boxing
    Foo(num)
End Sub

Sub Foo(ByVal obj As Object)
    Console.WriteLine(obj.GetType)
    Console.WriteLine(obj.ToString)
End Sub

Automatic Unboxing

The runtime can automatically unbox a boxed value:

// C#
static void Main()
{
    // Automatic Boxing
    object num = 25;

    // Automatic Unboxing – not really works
    Foo(num);
}

static void Foo(byte obj)
{
    Console.WriteLine(obj.GetType());
    Console.WriteLine(obj.ToString());
}
' VB.NET
Sub Main()
    ' Automatic Boxing
    Dim num As Object = 25

    ' Automatic Unboxing - works
    Foo(num)
End Sub

Sub Foo(ByVal obj As Byte)
    Console.WriteLine(obj.GetType)
    Console.WriteLine(obj.ToString)
End Sub

The difference between C# and VB.NET in the last situation is that VB.NET allows automatic unboxing while C# doesn’t. (Theoretically, VB.NET allows automatic conversion between the vast majority of types, while C# lacks this feature.)

Summary

That was a brief discussion of value types and reference types in .NET Framework. Value types are those normally when passed to a function or copied, a copy of the value is used not the original value. Therefore, changes made to that copy don’t affect the original object.

On the other hand, reference types are those when passed to a function or copied, the object itself is used. Therefore, any changes made inside the function or to the copy do affect the original object (both are the same.)

Value types in .NET are all types inherit from System.ValueType including structures, enumerations, and primitives. All other classes don’t inherit from System.ValueType are reference types.

Boxing is the process of converting a value type to reference type. Unboxing is retrieving that boxed reference type back. To box a variable simple convert it to System.Object. To unbox it, convert it back to its original type. Boxing could also occur automatically when you pass a value type to a function that accepts System.Object not the type itself.

Setting Device Information in MCI

هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

Interested in MCI multimedia processing? First check this article out if you didn’t:

Creating a Sound Recorder in C and C#

After we received your feedbacks and comments about th.e article, we decided to add a small appendix to the end of the article about setting information (volume, channel, sampling rate, etc.) to a MCI device (a Waveform device of course.)

Like anything else in MCI, you can set device information using a MCI command (string/numeric), and this time it’s the MCI_SET command.

This command is used to set information about a specific device. This command requires an input parameter of the MCI_SET_PARMS structure. However, that input parameter might have extended members for specific devices. Because we are concentrating of Waveform devices, so we are going to use the MCI_WAVE_SET_PARMS structure that contains the extended members for our device and is defined as following:

typedef struct {
    DWORD_PTR dwCallback;
    DWORD     dwTimeFormat;
    DWORD     dwAudio;
    UINT      wInput;
    UINT      wOutput;
    WORD      wFormatTag;
    WORD      wReserved2;
    WORD      nChannels;
    WORD      wReserved3;
    DWORD     nSamplesPerSec;
    DWORD     nAvgBytesPerSec;
    WORD      nBlockAlign;
    WORD      wReserved4;
    WORD      wBitsPerSample;
    WORD      wReserved5;
} MCI_WAVE_SET_PARMS;

This structure contains all and every little piece of information that can be set to a device. I expect that you read the main article and you are already familiar with members like dwCallback (other members are self-explanatory) that we have talked about many times, and you are fine too with function calls and setting up input parameters, so I won’t get into the discussion of the structure or how you are going to use that command. However, if you need more help setting up the input parameters for the structure, you should take a brief look at the MCI_WAVE_SET_PARMS Structure documentation in the MSDN.

As you know, the MCI_WAVE_SET_PARMS unmanaged structure can be marshaled in C# as following:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MCI_WAVE_SET_PARMS
{
    public IntPtr dwCallback;
    public uint     dwTimeFormat;
    public uint     dwAudio;
    public uint      wInput;
    public uint      wOutput;
    public ushort      wFormatTag;
    public ushort      wReserved2;
    public ushort      nChannels;
    public ushort      wReserved3;
    public uint     nSamplesPerSec;
    public uint     nAvgBytesPerSec;
    public ushort      nBlockAlign;
    public ushort      wReserved4;
    public ushort      wBitsPerSample;
    public ushort      wReserved5;
}

Congratulations! You did set the device information! So how to get them back?

This can be done through the MCI_STATUS (discussed earlier) by setting up the MCI_STATUS_ITEM flag and setting the query item to the required information you need to query about (like MCI_DGV_STATUS_VOLUME to query about volume.)

More about the MCI_STATUS command can be found in the MSDN documentation.

Why you receive a System.Security.SecurityException exception!

Have you ever received an exception like this:

System.Security.SecurityException: xxx.

This exception is thrown whenever you try to access a protected resource while your code doesn’t have the required permissions.

.NET Framework helps protecting computer system from malicious code and software by using a nice feature of CLR called Code Access Security (simply, CAS.) This feature manages the permissions gained by .NET applications, allows code from known vendors and code running from secure locations to run seemlessly without interruption of the CLR, while holds other applications from unknown vendors and applications running from insecure locations (like network shares) to run with restrictions and limitation of access to shared system resources.

A great job from the author is done in the following article:

Understanding .NET Code Access Security

Manually performing a garbage collection!

I was asked whether it’s efficient to perform a manual garbage collection using GC.Collect() or not!

Actually, it’s better to just let the CLR handle it. However, there’re few circumstances where manually performing garbage collection is preferred, such as if some non-recurring event has just happened and this event is highly likely to have caused a lot of old objects to die.

More details are available in Rico Mariani’s…

Have a nice weekend!

Serialization vs. Marshaling

هذه المقالة متوفرة أيضا باللغة العربية، اقرأها هنا.

Overview

Are you somewhat confused between Serialization and Marshaling? This writing would break this confusion up, it would give you a basic understanding of the process of Serialization and the process of Marshaling, and how you can get the most out of each.

Serialization

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file, a memory buffer, or transmitted across a network connection to be “resurrected” later in the same or another computer environment. And this sequence of bits can be of any format the user chooses; however, they are usually formed as XML or binary.

Serialization comes in many forms in .NET Framework, it can be observed in ADO.NET, Web services, WCF services, Remoting, and others.

For example, calling the WriteXml() function of a DataSet serializes this DataSet into a XML file.

    ds.WriteXml("data.xml");

And if we have such this structure:

    public struct User
    {
        public int id;
        public string name;
    }

we can get the following results if we serialize a collection of that structure into XML:



    
        12
        Mark
    
    
        13
        Charles
    
    
        14
        John
    

Serialization can be observed in Web and WCF services too. The request and parameter information for a function are serialized into XML, and when the function returns the response and the returned data too are serialized into XML. Actually, you don’t have to think about these XML data, CLR handles this for you.

In the same vein, when it comes to Remoting, the sender and recipient must agree to the same form of XML data. That’s, when you send some data CLR serializes this data for you before it sends it to the target process. When the target process receives this XML data, it turns it back (deserializes it) to its original form to be able to handle it.

Thus, the process of converting data structures and objects into series of bits is called Serialization. The reverse of this process, converting these bits back to the original data structures and objects, is called Deserialization.

Therefore, the following ADO.NET line does deserializes the XML file:

    DataSet ds;
    ds.ReadXml("data.xml");

And when your application receives response from the server or from another process, the CLR deserializes that XML data for you.

So why XML is preferred over binary serialization? That’s because XML is text-based. Thus, it’s free to be transmitted from a process to another or via a network connection, and firewalls always allow it.

Marshaling

Marshaling is the process of converting managed data types to unmanaged data types. There’re big differences between the managed and unmanaged environments. One of those differences is that data types of one environment is not available (and not acceptable) in the other.

For example, you can’t call a function like SetWindowText() -that sets the text of a given window- with a System.String because this function accepts LPCTSTR and not System.String. In addition, you can’t interpret (handle) the return type, BOOl, of the same function, that’s because your managed environment (or C# because of the context of this writing) doesn’t have a BOOL, however, it has a System.Boolean.

To be able to interact with the other environment, you will need to not to change the type format, but to change its name.

For example, a System.String is a series of characters, and a LPCTSTR is a series of characters too! Why not just changing the name of the data type and pass it to the other environment?

Consider the following situation. You have a System.String that contains the value €œHello€:

System.String str = "Hello";

The same data can be represented in an array of System.Char too, like the following line:

System.Char[] ch = str.ToCharArray();

So, what is the difference between that System.String variable and that System.Char array? Nothing. Both contain the same data, and that data is laid-out the same way in both variables. That’s what Marshaling means.

So what is the difference between Serialization and Marshaling?

C# has a System.Int32, and Windows API has an INT, and both refer to a 32-bit signed integer (on 32-bit machines.) When you marshal the System.Int32 to INT, you just change its type name, you don’t change its contents, or lay it in another way (usually.) When you serialize a System.Int32, you convert it to another form (XML for instance,) so it’s completely changed.

Summary

Look, after I get back to Wikipedia documentation for Marshaling, I realized that my answer was so specific to C#!

I mean that, Marshaling is a very general term used to describe transformations of memory. Theoretically, it’s more general than Serialization. In Python for instance, the terms Marshaling and Serialization are used interchangeably. There (in Python,) Marshaling = Serialization, and Serialization = Marshaling, there’s no difference. In computer methodology, there’s a silent difference between Marshaling and Serialization (check the Wikipedia definition.)

So what is that System.MarshalByRefObject class? Why that name -specifically- was used? First, System.MarshalByRefObject class allows objects to be passed by reference rather than by value in applications that use Remoting.

Personally, I like to say that Microsoft .NET Framework team’s name was very scientific when they have called that object “MarshalByRefObject” with respect to that silent difference between serialization and marshaling or maybe that name was derived from Python, dunno!

After all, we should keep in mind that in .NET methodology, there’s a big difference between Serialization and Marshaling, Marshaling usually refers to the Interop Marshaling. In .NET Remoting, it refers to that serialization process.

By the way, Marshalling is so named because it was first studied in 1962 by Edward Waite Marshall, then with the General Electric corporation.

That’s all.

Have a nice day!