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

 
 
よくまとまっていそうなので、メモ。
あとでよく読んでみよう・・・と思う前に、読んで試してみた。。。
 
メモリーはこんな感じ。
さすがにW-ZERO3はゼロスピンドルなので、ページファイルは何も帰ってこなかった。w
        private struct MEMORY_STATUS
        {
            public uint dwLength;
            public uint dwMemoryLoad;
            public uint dwTotalPhys;
            public uint dwAvailPhys;
            public uint dwTotalPageFile;
            public uint dwAvailPageFile;
            public uint dwTotalVirtual;
            public uint dwAvailVirtual;
        }
        [DllImport("coredll.dll", SetLastError=true)]
        private static extern void GlobalMemoryStatus(ref MEMORY_STATUS ms);
        private MEMORY_STATUS GetMemStatus()
        {
            MEMORY_STATUS ms = new MEMORY_STATUS();
            GlobalMemoryStatus(ref ms);
            return ms;
        }
————-
CPU負荷も、こんなことしないとだめなのね・・・

TextureBrush OutOfMemoryException with .NET Compact Framework 2.0

I encounterd TextureBrush OutOfMemoryException with .NET Compact Framework 2.0.
 
Environment:
           Visual Studio 2005 Team Suite / Japanese version.
           .NET Compact Framework 2.0 Service Pack 1
           Sharp W-ZERO3 WS004SH for the target machine.
          
By using TextureBrush with extensive FillPolygon results in OutOfMemoryException.
Forcing GC does not help.
I used the using pattern, and those instances should have no leak.
 
If I replace
                g.FillPolygon(textureBrush, drawArea);
          with g.FillRectangle(textureBrush, 0,0,100,100);
then, it works fine.
Therefore, it could be a potential bug of .NET Compact Framework 2.0.
 
I have checked out the same symptom by the Google and found a few people reported same issue.
But, there seems to be no solution yet.
—————–
// Run following code and wait for a few minutes, then results in the exception.
// Please note that you have to add a timer with 100mSEC interval and enabled state.
—————–
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace TextureBrushOutOfMemory1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            this.Invalidate();
        }
        private Bitmap backBuffer = null;
        Point[] drawArea = { new Point(10, 10), new Point(90, 10), new Point(90, 90), new Point(10, 90) };
        Bitmap bmp = null;
        Random rnd = new System.Random();
        private void Form1_Paint_1(object sender, PaintEventArgs e)
        {
            using (Graphics g = e.Graphics)
            {
                doPaint(sender, g);
            }
        }
        private void doPaint(object sender, Graphics gr)
        {
            // Make a new back buffer if needed.
            if (backBuffer == null)
            {
                backBuffer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            }
            if (bmp == null)
                bmp = new Bitmap(100, 100);
            // Create Image for TextureBrush
            using (Graphics g = Graphics.FromImage(bmp))
            using (SolidBrush redBrush = new SolidBrush(Color.Red))
            using (SolidBrush blueBrush = new SolidBrush(Color.Blue))
            {
                float val = 0.5F;
                g.FillRectangle(redBrush, 0, 0, 100, 100);
                for (int i = 0; i < rnd.Next(300); i++)
                {
                    g.FillRectangle(blueBrush, (int)(val * rnd.Next(100)), 100 – (int)(val * rnd.Next(100)), (int)(val * rnd.Next(50)), (int)(val * rnd.Next(50)));
                }
            }
            // FillPolygon on the backBuffer with textureBrush
            using (Graphics g = Graphics.FromImage(backBuffer))
            using (TextureBrush textureBrush = new TextureBrush(bmp))
            {
                g.FillPolygon(textureBrush, drawArea);
                // g.FillRectangle(textureBrush, 0,0,100,100);
                // FillRectangle works fine.
                // But, FillPolygon results in Out of Memory Exception.
            }
            // Force GC by GC.Collect() or WaitForPendingFinalizers() is not effective.
            GC.Collect();
            GC.WaitForPendingFinalizers();
            // Draw the backBuffer to the FormWindow
            gr.DrawImage(backBuffer, 0, 0);
        }
        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            // avoid flicker
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

レジストリー ハイブ / Registry Hive

Registry Hive は、外部 (リモート) コンピュータ上の要求されたキーの最上位ノードを表します。最上位ノードは次のとおり。
  • ClassesRoot
  • CurrentConfig
  • CurrentUser
  • DynData
  • LocalMachine
  • PerformanceData
  • Users

MSDNに説明がちょこっとだけ載っていますが、見つけにくいのでとりあえずメモ。

.NET Compact Framework でサポートされていない機能

.Net Compact Framework で何かを作ろうとした際に、今まで当たり前に .NET Framework でできていたことが、できない設計になっているので、戸惑います。ここでは、その情報をまとめておきます。

 

GDI+

GDI+がサポートされていない。Region が使えないのは痛い。
Direct3Dはサポートされているがどこまでできるかは不明。

Method

オーバーライド 多くのメソッドオーバーライドができなくなっている。

コントロール

印刷系はばっさり。CrystalReportViewer, PageSetupDialog, PrintDialog, PrintDocument, PrintPreviewControl, PrintPreviewDialog
 

Binary シリアライズ

BinaryFormatter, SoapFormatterはサポートされない。
 

レジストリーアクセス

Microsoft.Win32.Registry 名前空間は使えない。Windows CE のレジストリは、Windows API経由でアクセスする。
 

COM

C++ でアンマネージドCOMを作成する。次に、PInvokeにより DLL のラッパーを作る。
 

セキュリティ

アンマネージドコードへのセキュリティは提供されない。どのアプリケーションでもシステムAPIにアクセス可能。
.NET Compact Framework はロールベースのセキュリティは提供しない。
 

リモーティング

リモーティングはサポートされていない。
 
 
 
 
 
 
 
 
 

コントロール

印刷系はばっさり。CrystalReportViewer, PageSetupDialog, PrintDialog, PrintDocument, PrintPreviewControl, PrintPreviewDialog
コントロール自体同じ名前でも、中身がサポートされていない機能が結構ある。
たとえば、PictureBoxの OnPaint、Region もない。

XML

System.Xml.XPath namespace, XSLTなどがサポートされない。

Web Services

System.Web では、クライアントは作れるけどサービスは作れない。普通はそんなことしないので問題ない。

Database Support

ローカルデータベースとして SQL Server CE がサポートされる。SQL Server のクライアントとしてもOK。

 

 

 

 

 

 

 
 

vista RC2 5744 にアップ

どうも、ISO DVD がうまく焼けない。
ワークアラウンドで、次の手順でインストール。
 
1. ISO イメージを Virtual Server にマウント。
2. ゲストPC上では、ディレクトリの形で見えるので、それをターゲットPCの D Drive に単純コピー。
3. ターゲットPC (Vista RC1) から、D Drive の Setup.exe を起動。
 
問題なく、アップデート完了。今のところ、英語キーボードが日本語キーボードで認識されてしまう以外、大きな問題なし。
ブラインドタッチで打てて、よかった・・・でもバックスラッシュは困るんだよね。
 
速度的には、あまり早くなったような気はしない。
 
// 宇宙仮面
 

W-ZERO3 の Launcher を作ってみた。

W-ZERO3 で ie を起動したり、opera を起動したり、AltEscape を使ったり、TaskManager を起動したりと、面倒なので Launcher を作ってみた。
予想以上におくが深いことを発見。
 
へーーーーっ、って感じ。
 
Pocket PC, Windows CE 5.0 など言葉の定義から、開発環境から、Windows CE の制限、.NET Framework の制限など・・・・
explorer.exe のスペルが explore.exe だったりして、気がつかずに起動できずに悩んだり・・・
ちょっとしたローンチャー作るにも、情報が整理されていないので、調べるところからなので、結構大変。
 
わかってしまえば何のことはないのだろうけど・・・
 
// 宇宙仮面
 

W-ZERO3 開発環境

1. Visual Studio 2005
2. ActiveSync 4.2
 
ActiveSync をPCにインストールし、W-ZERO3 と接続状態にしておき、PC側で .NET Compact Framework をインストールすると W-ZERO3 側に自動的に   .NET Compact Frameworkがインストールされる。
ただし、Virtual Server/Virtual PC 上で環境を構築していると、.NET Compact Framework 2.0 をActiveSync 経由でW-ZERO3 に入れる場合ことはできない。
別のPCを使って、 .NET Compact Frameworkを入れる必要がある。
 
Virtual PC/Virtual Server だと、リモート接続、リモートデバッグができないので、本格的にやる場合は1台専用に開発マシンを用意したほうがよい。
 
// 宇宙仮面

NET Compact Framework 2.0 を W-ZERO3 にインストールするには

.NET Compact Framework 2.0 を W-ZERO3 にインストールするには、
1. Active Sync V4.1 でW-ZERO3 をPCに接続。
2. PC 上で .NET Compact Framework 2.0 のインストーラを実行。
3. すると、W-ZERO3 上にも自動的にインストールされる。
 
 
 

スマート デバイス プロジェクトの種類の選択

VS2005でアプリケーションを配置しようとすると、配置する場所を選択するためのダイアログが表示される。
選択肢は、
Pocket PC 2003 SE VGA エミュレータ
Pocket PC 2003 SE エミュレータ

Pocket PC 2003 SE 四角 VGA エミュレータ

Pocket PC 2003 SE 四角 エミュレータ

Pocket PC 2003 SE デバイス
Windows CE 5.0 デバイス
 
Pocket PC 2003: 「Windows Mobile(TM) 2003 software for Pocket PC」
Windows CE 5.0: 2004/7 発表

 
Windows CE: 家電を意味するConsumer Electronicsの略といわれているが、正式には不明。

W-ZERO3に搭載されている.NET Compact Framework 1.0は SP3。