.NET Framework บน Linux

    Ximian เป็นบริษัทที่ผลิต Software แบบ Open Source ป้อนให้ตลาด Linux มีผลงานมาแล้วหลายชิ้น เมื่อ 2-3 เดือนก่อน Ximian ประกาศจะ Implement .NET Framework บน Linux โดยใช้ draft spec  ที่ Microsoft ส่งให้กับ ECMA เพื่อขอประกาศเป็นมาตรฐาน

    Ximian ทำงานแบบทุ่มพลังสร้างจริงๆ มี update มาเป็น snapshot ทุกวัน เรามาลองดูว่า Ximian จะทำอะไรบ้าง แล้วทำไปถึงไหนแล้ว

    สิ่งหลักๆ ที่ Ximian จะทำ มีอยู่ 3 ส่วนคือ

  1. .NET Framework Runtime (CLR)

  2. .NET Framework base Library

  3. C# Compiler

.NET Framework Runtime (CLR)

    Ximian ตั้งชื่อ project ในการทำ .NET Framework บน Linux ว่า Mono เรามาดูกันดีกว่าว่า Ximian ทำอะไรไปถึงไหนแล้ว

    ผม Download Snapshot รุ่นล่าสุดวันที่ 13-SEP-01 จาก site http://www.go-mono.com เมื่อ compile โปรแกรมแล้ว จะมีโปรแกรมหลักๆ อยู่ 3 ตัวดังนี้ครับ

Linux  Prompt

-[~/mono] ls -l monodis mint pedump
-rwxr-xr-x 1 root root 263045 Sep 14 10:23 monodis
-rwxr-xr-x 1 root root 329326 Sep 14 10:23 mint
-rwxr-xr-x 1 root root 200580 Sep 14 10:23 pedump

[~/mono] _

เรามาดูรายละเอียดกันทีละตัวครับ

mint

    โปรแกรมนี้คือโปรแกรม .NET Framework Runtime บน Linux นั่นเอง คุณสามารถเอาโปรแกรมที่เขียนโดยใช้ .NET Framework บน Windows มาใช้งานได้เลย แต่ในขณะนี้รองรับเพียงโปรแกรมง่ายๆ อย่าง Hello, World เท่านั้นครับ (อาจจะรองรับมากกว่านี้ แต่ผมไม่มีเวลาทดสอบครับ) เรามาลองทดสอบ mint กันดีกว่าครับ

    เริ่มจากผมมีโปรแกรม Hello, World ดังนี้ครับ

hello.cs

using System;

class
Hello
{
  
public static void Main()
   {
     
Console.WriteLine("Hello, World");

      }
}

โปรแกรมนี้อยู่บน Windows ธรรมดา ต่อมาผมก็ใช้ csc.exe เพื่อคอมไพล์โปรแกรมตามปกติ

DOS Prompt

C:\CS>csc hello.cs
Microsoft (R) Visual C# Compiler Version 7.00.9254 [CLR version v1.0.2194]
Copyright (C) Microsoft Corp 2000-2001. All rights reserved.

C:\cs>dir hello.*
Volume in drive C has no label.
Volume Serial Number is 1F1E-13D8

Directory of C:\cs

09/14/2001 12:16p       3,072 hello.exe
09/01/2001 02:55p         111 hello.cs
              2 File(s) 3,183 bytes
              0 Dir(s) 14,136,147,968 bytes free

C:\cs>_

จากนั้นผมก็ copy โปรแกรม hello.exe ไปที่ Linux จากนั้นลองพิมพ์คำสั่งดังนี้ดูครับ

Linux Prompt

[~/mono] mint
mint 0.6, the Mono ECMA CLI interpreter, (C) 2001 Ximian, Inc.

Usage is: mint [options] executable args...
Valid Options are:
--trace
--opcode-count

[~/mono] mint hello.exe
Hello, World

[~/mono] _

จะเห็นได้ว่า ผมสามารถรัน hello.exe ที่สร้างจาก Windows บน Linux ได้ทันทีครับ

pedump

    pedump เป็นโปรแกรมที่ดูโครงสร้างของแฟ้ม .exe ที่เป็น Managed code เราเลยลองเอามาแอบดู hello.exe ดังนี้ครับ

Linux Prompt

[~/mono] pedump hello.exe

COFF Header:
Machine: 0x014c
Sections: 0x0002
Time stamp: 0x3b9711d6
Pointer to Symbol Table: 0x00000000
Symbol Count: 0x00000000
Optional Header Size: 0x00e0
Characteristics: 0x010e

PE Header:
Magic (0x010b): 0x010b
LMajor (6): 0x06
LMinor (0): 0x00
Code Size: 0x00000400
Initialized Data Size: 0x00000200
Uninitialized Data Size: 0x00000000
Entry Point RVA: 0x000022de
Code Base RVA: 0x00002000
Data Base RVA: 0x00004000


NT Header:
Image Base (0x400000): 0x00400000
Section Alignment (8192): 0x00002000
File Align (512/4096): 0x00000200
OS Major (4): 0x0004
OS Minor (0): 0x0000
User Major (0): 0x0000
User Minor (0): 0x0000
Subsys major (4): 0x0004
Subsys minor (0): 0x0000
Reserverd: 0x00000000
Image Size: 0x00006000
Header Size: 0x00000200
Checksum (0): 0x00000000
Subsystem: 0x0003
DLL Flags (0): 0x0000
Stack Reserve Size (1M): 0x00100000
Stack commit Size (4096): 0x00001000
Heap Reserve Size (1M): 0x00100000
Heap Commit Size (4096): 0x00001000
Loader flags (0x1): 0x00000000
Data Directories (16): 0x00000010

Data directories:
Export Table: 0x00000000 [0x00000000]
Import Table: 0x00002290 [0x0000004b]
Resource Table: 0x00000000 [0x00000000]
Exception Table: 0x00000000 [0x00000000]
Certificate Table: 0x00000000 [0x00000000]
Reloc Table: 0x00004000 [0x0000000c]
Debug: 0x00000000 [0x00000000]
Copyright: 0x00000000 [0x00000000]
Global Ptr: 0x00000000 [0x00000000]
TLS Table: 0x00000000 [0x00000000]
Load Config Table: 0x00000000 [0x00000000]
Bound Import: 0x00000000 [0x00000000]
IAT: 0x00002000 [0x00000008]
Delay Import Desc: 0x00000000 [0x00000000]
CLI Header: 0x00002008 [0x00000048]

Name: .text
Virtual Size: 0x000002e4
Virtual Address: 0x00002000
Raw Data Size: 0x00000400
Raw Data Ptr: 0x00000200
Reloc Ptr: 0x00000000
LineNo Ptr: 0x00000000
Reloc Count: 0x0000
Line Count: 0x0000
Flags: code, exec, read,

Name: .reloc
Virtual Size: 0x0000000c
Virtual Address: 0x00004000
Raw Data Size: 0x00000200
Raw Data Ptr: 0x00000600
Reloc Ptr: 0x00000000
LineNo Ptr: 0x00000000
Reloc Count: 0x0000
Line Count: 0x0000
Flags: data, discard, read,

CLI header size: 72
Runtime required: 2.0
Flags: ilonly, 32/64, trackdebug
Metadata: 0x0000207c [0x00000214]
Entry Point Token: 0x06000001
Resources at: 0x00000000 [0x00000000]
Strong Name at: 0x00000000 [0x00000000]
Code Manager at: 0x00000000 [0x00000000]
VTableFixups at: 0x00000000 [0x00000000]
EAT jumps at: 0x00000000 [0x00000000]

Metadata pointers:
Tables (#~): 0x0000006c - 0x0000012c [192 == 0x000000c0]
Strings: 0x0000012c - 0x000001cc [160 == 0x000000a0]
Blob: 0x000001f8 - 0x00000214 [28 == 0x0000001c]
User string: 0x000001cc - 0x000001e8 [28 == 0x0000001c]
GUID: 0x000001e8 - 0x000001f8 [16 == 0x00000010]
Rows:
Table Module: 1 records (10 bytes, at 0x4001d320)
Table TypeRef: 2 records (6 bytes, at 0x4001d32a)
Table TypeDef: 2 records (14 bytes, at 0x4001d336)
Table Method: 2 records (14 bytes, at 0x4001d352)
Table MemberRef: 2 records (6 bytes, at 0x4001d36e)
Table StandaloneSig: 1 records (2 bytes, at 0x4001d37a)
Table Assembly: 1 records (22 bytes, at 0x4001d37c)
Table AssemblyRef: 1 records (20 bytes, at 0x4001d392)
RVA for Entry Point: 0x00002050

[~/mono] _

monodis

    monodis เป็นโปรแกรมที่แสดงให้เห็นถึงภาษา MSIL ของ .exe นั้น เรามาดูกันครับ

Linux Prompt

[~/mono] monodis hello.exe
 
.assembly extern mscorlib
{
  .ver 1:0:2411:0
}
.assembly 'AssemblyName'
{
  .hash algorithm 0x00008004
  .ver  0:0:0:0 
}
  .class private auto ansi beforefieldinit Hello
  	extends [mscorlib]System.Object
  {
    .method public static 
           default void Main()  cil managed 
    {
        // Method begins at RVA 0x2050
	.entrypoint
	// Code size 11 (0xb)
	.maxstack 1
	IL_0000: ldstr "Hello, World"
	IL_0005: call void [mscorlib]System.Console::WriteLine(string)
	IL_000a: ret 
    }

    .method public specialname  rtspecialname 
           instance default void .ctor()  cil managed 
    {
        // Method begins at RVA 0x2068
	// Code size 7 (0x7)
	.maxstack 2
	IL_0000: ldarg.0 
	IL_0001: call instance void [mscorlib]System.Object::.ctor()
	IL_0006: ret 
    }
  }

[~/mono] _

.NET Framework based class Library

    การ Implement Library ของ .NET นั้น มีความคืบหน้ายิ่งกว่าส่วนอื่นๆ ถ้าคุณสนใจสถานะว่า Library ตัวไหนทำไปแล้วมาน้อยเพียงใด ดูได้จาก http://www.go-mono.com/class-status/index.html

C# Compiler

    Ximian ทำคอมไพเลอร์ภาษา C# ที่ชื่อว่า mcs (Mono CSharp compiler) เอาไว้ด้วย ความคืบหน้าในขณะนี้ ก็สามารถคอมไพล์โปรแกรมง่ายๆ อย่าง Hello, World ได้แล้วเช่นกัน แต่ในขณะนี้ mcs ทำงานได้บน Cygwin ซึ่งเป็น Linux บน Windows NT เท่านั้น (Cygwin คล้าย DOS Prompt บน Windows แต่ Prompt นั้นเป็น Linux Prompt และ แฟ้มแยกจาก Windows อย่างอิสระ) ยังไม่สามารถใช้งานได้กับ Linux แท้ๆ ทั้งนี้ก็เนื่องจาก mcs นั้นเขียนด้วยภาษา C# ไม่ใช่ภาษา C เลยต้องอาศัย Cygwin เพื่อเรียกเข้าไปที่ Windows แล้วใช้ csc.exe ของ Microsoft เพื่อคอมไพล์ ที่ Ximian ทำแบบนี้ก็เพราะเขาอยากเรียน C# ให้ถึงแก่น เลยลองเขียน Compiler ภาษา C# ด้วยภาษา C# แต่พอรุ่นที่เอาจริง ก็จะปรับเป็นภาษา C เพื่อคอมไพล์บน Linux แท้ๆ ได้ครับ

    อาจจะกล่าวได้อีกอย่างว่า mcs รุ่นนี้ เป็นรุ่นบน Windows ครับ แค่เพียงอาศัย Cygwin เป็นที่ compile ครับ ผลลัพธ์ออกมาก็เป็น .exe ที่เป็น managed code ครับ

    เรามาลองดู mcs กัน

Dos Prompt

C:\cs>dir compiler.exe
Volume in drive C has no label.
Volume Serial Number is 1F1E-13D8

Directory of C:\cs

09/14/2001 11:10a           245,760 compiler.exe
            1 File(s)       245,760 bytes
            0 Dir(s) 14,123,302,912 bytes free

C:\CS> compiler --help
compiler [options] source-files

-v         Verbose parsing
-o         Specifies output file
-L         Specifies path for loading assemblies
--nostdlib Does not load core libraries
--target   Specifies the target (exe, winexe, library, module)
--dumper   Specifies a tree dumper
-r         References an assembly

C:\CS> compiler hello.cs
C:Parsing successful
Loading: mscorlib
FIXME: IsNamespace returns false always!
TODO: Maybe we need a pop here?
Success

C:\cs> dir hello.*

olume in drive C has no label.
Volume Serial Number is 1F1E-13D8

Directory of C:\cs

09/14/2001 01:316p      2,048 hello.exe
09/01/2001 02:55p         111 hello.cs
              2 File(s) 2,159 bytes
              0 Dir(s) 14,136,147,968 bytes free

C:\cs> hello Hello, World C:\cs> _

จะเห็นได้ว่า msc สามารถคอมไพล์โปรแกรม Hello, World ได้ และได้เล็กกว่า csc.exe เสียอีก แต่นั่นไม่ใช่จุดที่เรามาคุยกันครับ เพียงแค่ต้องการชี้ให้เห็นว่า มันคือคนละตัวกันครับ

 

มุมมอง

    มาถึงมุมมองของผมเอง ผมมีความเห็นว่า project Mono เป็น project ที่มีอนาคตครับ ในไม่ช้านี้ เราอาจจะสามารถรันโปรแกรม .NET .exe บน Linux ได้ และด้วย project Mono ตัวนี้เป็น Open Source มันจะส่งผลให้ คนอื่นสามารถเอา Source Code ตัวนี้ ไป port บน OS ต่างๆ ได้โดยง่าย ซึ่งมันจะเทียบเท่า Java ในแง่ของ Portablity ในที่สุด ใครที่พูดว่า .NET Framework จะอยู่บน Windows เท่านั้น คิดผิดคิดใหม่ได้ครับ

    Ximian ประกาศทำ .NET Library ในส่วน GUI ด้วย ซึ่งก็ไม่ใช่เรื่องที่ยากเกินความสามารถของ Ximian ครับ เพราะ Ximian นั้นเป็นผู้เชี่ยวชาญ GNOME ซึ่งเป็น GUI บน Unix อยู่แล้ว หมายกำหนดการคือ 1 ปีครับ