WZero3 用 Windows Live for Mobile

W-ZERO3 用 Windows Live for Windows Mobile がリリースされていて、今週は結構オンラインになっていました。帰宅途中で家にチャットするのも結構面白い。
 
 
ただ、オンラインだと、かなりバッテリーが早くなくなるような気がします。

MS用語

当たり前のごつくつかわれているけど・・・
 
CTP    Community Technology Preview   コミュニティ向けの限定リリース
QFE     Quic Fix Engineering  応急的な修正プログラム
RTM    Release To Manufacturing   製造のためのバージョン(アルファ、ベータ1、ベータ2、RC1、RC2を経て、最終段階のRTMとなる)
 

.NET Compact Framework 3.5

Visual Studio Orcas March CTP を入れながら、.NET Compact Framework 3.5 になっている。
 
によると、4つのエリアにフォーカスして開発中とのこと。
    1. 分散モバイルアプリケーションを作成するため、WCF(Windows Communication Foundation)との連携を可能とする
    2. デバイス固有のフィーチャーをLINQで実装
    3. 要求の高い機能の実現
    4. ダイアグと信頼性解決とサポートの問題のための機能をリファイン

New Features Included in the Orcas January CTPでの新しい機能は次の通り

  • • HTTP compressionを含むSystem.IO.Compression のサポート
  • • LINQ の標準クエリオペレータのサブセットをサポート
  • • WaveOut による同時サウンドプレイを可能にする SoundPlayerのサポート.
  • • Smartphone and Pocket PCの識別を容易にするMicrosoft.WindowsCE.Forms の新しいAPI
  • • ネストしたFuncEvalを可能にする。??
  • • InterOpのログの強化
  • • Stack Trace の強化.
  • • GACの改良.
  • • StrongName keysを1024以上に対応.
  • • ファイナライザーの動作をログする機能を強化.(サポートのため)
  • . log fileを実行時に読み取り可能にする
 
 

Visual Studio Orcas Beta 1 ダウンロード開始

March CTP をさっきインストール終わって、触ってみるかと思いつつ・・・
あれ? Beta 1 でてるじゃん・・・ orz
ということで Beta 1ダウンロード中。おそ!
ISOで自分でインストールか、Virtual Image でインストール済みのイメージも提供されている。
 

アクセスカウンターがいつの間にかサービス停止になっていた

Infoseek のアクセスカウンターがいつの間にかサービス停止になっていたので、忍者ツールへ変更。
カウンターは、Infoseek アクセス解析
 
3日坊主の割には、よく続いていると思う。
MVP アワードもらっていなかったら、確実に終わっていたと思う。
やっぱり、いろいろな人と出会えたのが最高に刺激を受けましたね。
 
2002/3/3 新規作成。祝:初公開!
Microsoft は嫌いだけれど、Java もメモリ食いで使い物にならないし。。。
MFC, Win32 よりはまだましかと、ついに魂を悪魔に売り渡して、C# Programming の勉強をはじめました。
bar トータルアクセス数 5319791
bar 重複を除いたユニークアクセス数 2363679
 
2003年11月29日(土) 0 0 0 0 0.00
2003年11月30日(日) 435 435 573 573 1.32
…. 中略
2007年 4月13日(金) 3798 2357587 7808 5307146 2.06
2007年 4月14日(土) 1170 2358757 2204 5309350 1.88
2007年 4月15日(日) 1068 2359825 2282 5311632 2.14
2007年 4月16日(月) 3812 2363637 8099 5319731 2.12

W-Zero3 の.NETアプリを作ってみての感想

メリット
  • Visual Studio でほとんど違和感なく C# でアプリが組める。すごく楽。
デメリット
  • 結構メモリ食い。.NETアプリ4つも動かしたらアウトかも。
  • 起動が遅い。数秒待たされる。起動しておけばいいのだけど、メモリ食いなので、いまいち。
  • W-Zero3の機能(カメラ、通信など)を使おうと思うと、InterOpが必須になってしまい、結構面倒。

ちょこっとしたアプリを作って遊ぶ分にはいいかもしれないけれども、売り物を作ろうと思うと、ネイティブで作らないと厳しいと思う。InterOpするぐらいなら、最初から C++で書いたほうが早そう。というっことで、NGEN for Windows Mobile が欲しい!

 

 

 

WZero3の通信を切断する方法

RASの切断方法
            に書いてあるとおり。
 
呼び出し
            RasConn.CloseAllConnections();
—————–
using System;
using System.Runtime.InteropServices;
 
namespace Uchukamen.WZero3
{
    /// <summary>
    /// This class is based on code from "mikinder".
    /// http://www.developersdex.com/vb/message.asp?p=2916&r=5643969
    /// </summary>
    class RasConn
    {
        const int MAX_PATH = 260;
        const int RAS_MaxDeviceType = 16;
        const int RAS_MaxPhoneNumber = 128;
        const int RAS_MaxEntryName = 20;
        const int RAS_MaxDeviceName = 128;
        const int SUCCESS = 0;
        const int ERROR_NOT_ENOUGH_MEMORY = 8;
        const int RASBASE = 600;
        const int ERROR_BUFFER_TOO_SMALL = RASBASE + 3;
        const int ERROR_INVALID_SIZE = RASBASE + 32;
        #region DllImport
        //// — RASCONN data structure definition (refer to ras.h) —
        //private const int RAS_MaxEntryName = 20;
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct RASCONN
        {
            public int dwSize;
            public IntPtr hrasconn;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName + 1)]
            public string szEntryName;
        }
        // ——————————————–
        [DllImport("coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern uint RasEnumConnections(
            [In, Out] RASCONN[] rasconn,
            [In, Out] ref int cb,
            [Out] out int connections);
        [DllImport("coredll.dll")]
        private static extern uint RasHangUp(IntPtr pRasConn);
        #endregion
        /// <summary>
        /// Returns all active RAS connections as an array of data structure RASCONN
        /// </summary>
        /// <returns></returns>
        public static RASCONN[] GetAllConnections()
        {
            RASCONN[] tempConn = new RASCONN[1];
            RASCONN[] allConnections = tempConn;
            tempConn[0].dwSize = Marshal.SizeOf(typeof(RASCONN));
            int lpcb = tempConn[0].dwSize;
            int lpcConnections = 0;
            uint ret = RasEnumConnections(tempConn, ref lpcb, out lpcConnections);
            if (ret == ERROR_INVALID_SIZE)
            {
                throw new Exception("RAS: RASCONN data structure has invalid format");
            }
            else if (ret == ERROR_BUFFER_TOO_SMALL && lpcb != 0)
            {
                // first call returned that there are more than one connections
                // and more memory is required
                allConnections = new RASCONN[lpcb / Marshal.SizeOf(typeof(RASCONN))];
                allConnections[0] = tempConn[0];
                ret = RasEnumConnections(allConnections, ref lpcb, out lpcConnections);
            }
            // Check errors
            if (ret != SUCCESS)
            {
                throw new Exception("RAS returns error: " + ret);
            }
            if (lpcConnections > allConnections.Length)
            {
                throw new Exception("RAS: error retrieving correct connection count");
            }
            else if (lpcConnections == 0)
            {
                // if there are no connections resize the data structure
                allConnections = new RASCONN[0];
            }
            return allConnections;
        }
        /// <summary>
        /// Closes all active RAS connections
        /// </summary>
        /// <returns></returns>
        public static void CloseAllConnections()
        {
            RASCONN[] connections = GetAllConnections();
            for (int i = 0; i < connections.Length; ++i)
            {
                RasHangUp(connections[i].hrasconn);
            }
        }
    }
}

.NET Compact FrameworkのP/Invoke

WZero3 でアプリを書いていて、接続の制御をしようとして適当に書いていたら、動かない。ちょっと調べてみたら、.NET Compact Framework は .NET Framework のサブセットなので完全な .NET Framework の方法とはやや異なる。ということで、注意が必要。

Microsoft .NET Compact Framework の P/Invoke とマーシャリング入門

Microsoft .NET Compact Framework での高度な P/Invoke

 
ぐちゃぐちゃ書いてあって、わかりにくいので、簡単にポイントだけ整理する。
.NET Compact Framework の相違点の概要
    • SetLastError を true にすることを忘れないように。[DllImport("abc.dll", SetLastError=true)]
    • すべてが Unicode
    • Winapi(既定のCdecl) のみをサポート
    • .NET Compact FrameworkのP/Invokeは、 コールバックをサポートしない
    • EntryPointNotFoundException, ExecutionEngineExceptionのかわりに、 MissingMethodExceptionとNotSupportedExceptionが上がる
    • Formでは、ウィンドウハンドル (hwnd)、DefWndProc メソッドがサポートされない。MessageWindow、Messageクラスを使用して、他のウィンドウにメッセージを送信できる。サンプル コード… smartdevices.microsoftdev.com 。
    • 複合オブジェクト (参照型) をマーシャリングできないことがある。特に、構造体の中にstring配列があるような場合は注意。対応法方法は複数あり。

構造体内の文字列のマーシャリング

構造体内またはクラス内の文字列ポインタを正しくマーシャリングできない。対応方法は次の3つがある。
      • サンク層での呼び出し
      • unsafe ブロックの使用
      • 文字列ポインタを処理するカスタム クラスの作成

構造体内の固定長文字列のマーシャリング

System.Char の配列が実行時に配列への 4 バイト ポインタとしてマーシャリングされるので、構造体内の固定長文字列のマーシャリングは単純には動作しない。対応方法は2つ。
    • 正確な合計サイズのバイト配列を作成した後、構造体の各フィールドをバイト配列にコピーしたり、バイト配列からコピーする。 →複雑。
    • カスタム マーシャリングを組み合わせる方法。

——————

class Memory のC#版
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace Uchukamen.WZero3
{
    class Memory
    {
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern IntPtr LocalAlloc(int uFlags, int uByte);
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern IntPtr LocalFree(IntPtr hMem);
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern IntPtr LocalReAlloc(IntPtr hMem, int uBytes, int fuFlags);
        private const int LMEM_FIXED = 0;
        private const int LMEM_MOVEABLE = 2;
        private const int LMEM_ZEROINIT = 0x40;
        private const int LPTR = LMEM_FIXED | LMEM_ZEROINIT;
        // LocalAlloc を使用して、メモリ ブロックを割り当てます。
        public static IntPtr AllocHLocal(int cb)
        {
            return LocalAlloc(LPTR, cb);
        }
        // AllocHLocal で割り当てられたメモリを解放します。
        public static void FreeHLocal(IntPtr hlocal)
        {
            if (!hlocal.Equals(IntPtr.Zero))
            {
                if (!IntPtr.Zero.Equals(LocalFree(hlocal)))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                hlocal = IntPtr.Zero;
            }
        }
        // 以前に AllocHLocal で割り当てられたメモリ ブロックのサイズを変更します。
        public static IntPtr ReAllocHLocal(IntPtr pv, int cb)
        {
            IntPtr newMem = LocalReAlloc(pv, cb, LMEM_MOVEABLE);
            if (newMem.Equals(IntPtr.Zero))
            {
                throw new OutOfMemoryException();
            }
            return newMem;
        }
        // マネージ文字列の内容をアンマネージ メモリにコピーします。
        public static IntPtr StringToHLocalUni(string s)
        {
            if (s == null)
                return IntPtr.Zero;
            else
            {
                int nc = s.Length;
                int len = 2 * (1 + nc);
                IntPtr hLocal = AllocHLocal(len);
                if (hLocal.Equals(IntPtr.Zero))
                    throw new OutOfMemoryException();
                else
                {
                    Marshal.Copy(s.ToCharArray(), 0, hLocal, s.Length);
                    return hLocal;
                }
            }
        }
    }
}
 

RASCONN

結構面倒
  C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\Smartphone2003\Include\ras.h
#define RAS_MaxEntryName      20
RASCONNW
{
    DWORD    dwSize;
    HRASCONN hrasconn;
    WCHAR    szEntryName[ RAS_MaxEntryName + 1 ];
};

#define RASCONN RASCONNW

 
注意: sizeof RASCONN は、4 + 4 + 2 * ( RAS_MaxEntryName + 1 ) = 50 byteだけども、4byte バウンダリーになるため、52 byteになる。
————-
参考になるリンク