C」タグアーカイブ

MS 実装の csharp コマンドである “csi” コマンドを使ってみた。


みむらです。

今朝方、新潟の日本酒を飲みに行こうかなぁ・・ ( http://anisec.jp/yuzawa/ ) と思っていた所、
鋭敏電子の秋月さんも「こっ・・これはっ・・!」となる記事を見かけ、
いても経ってもいられず、移動中の車内で試してみることにしました。

記事としては次の記事。
http://blogs.msdn.com/b/visualstudio/archive/2015/10/08/visual-studio-2015-update-1-ctp.aspx

Visual Studio 2015 の Update 1 CTP がリリースされましたよという記事なのですが、
その中に、”Visual C# Interactive Compiler..” というものがありまして、
どうも見てみると、 mono の csharp コマンドのようなことをするプログラムのようで、
これは確かめなければっ・・! ということで現在に至ります。


使ってみた:

image

TAB による推測が出ないので、少し入力しづらいという点はありますが、
C# らしいコードを普通に書いて、ごにょごにょできるのはとても素晴らしいと思います。


インストール方法:

ダウンロードの URL がとても見つけづらいのですが、
Visual Studio 2015 Update 1 CTP
ここからダウンロードが可能です。

セットアップを開始すると、
image

こんな感じのおなじみの画面でセットアップが行われていきます。

終わりましたら、 「Visual Studio コマンドプロンプト」から “csi” コマンドで起動できます。

C# で ini ファイルの内容を任意のクラスに格納するコードを書いてみた。


どうもみむらです。

C# で ini ファイルを操作するとなると、
よくあるのが GetPrivateProfileString あたりを叩いて取得することになります。

でもその場合、いちいち要素を指定して取得しなければならず、
特に複数のキー(フィールド)がある場合に複数回コードを書くのも面倒です。

特に ini ファイルの項目が多くて、こんな状態になった日には・・。

image

 

・・ということで、 Reflection を使用して
この辺をすごく楽に出来るような感じでコードを書いてみました。

 

コード:

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

public static class Ini
{
    [DllImport("KERNEL32.DLL")]
    public static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, uint nSize, string lpFileName);

    [DllImport("KERNEL32.DLL")]
    public static extern uint GetPrivateProfileInt(string lpAppName, string lpKeyName, int nDefault, string lpFileName);

    [DllImport("KERNEL32.DLL")]
    public static extern uint WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);

    public static T Read<T>(string section, string filepath)
    {
        T ret = (T)Activator.CreateInstance(typeof(T));

        foreach (var n in typeof(T).GetFields())
        {
            if (n.FieldType == typeof(int))
            {
                n.SetValue(ret, (int)GetPrivateProfileInt(section, n.Name, 0, Path.GetFullPath(filepath)));
            }
            else if (n.FieldType == typeof(uint))
            {
                n.SetValue(ret, GetPrivateProfileInt(section, n.Name, 0, Path.GetFullPath(filepath)));
            }
            else
            {
                var sb = new StringBuilder(1024);
                GetPrivateProfileString(section, n.Name, "", sb, (uint)sb.Capacity, Path.GetFullPath(filepath));
                n.SetValue(ret, sb.ToString());
            }
        };

        return ret;
    }

    public static void Write<T>(string secion, T data, string filepath)
    {
        foreach (var n in typeof(T).GetFields())
        {
            WritePrivateProfileString(secion, n.Name, n.GetValue(data).ToString(), Path.GetFullPath(filepath));
        };
    }
}

 

使い方:

ini ファイルの読み取りたいセクションに合わせたクラスを用意します。

    public class Human
    {
        public string name;
        public int age;
    }

でもって次のような ini ファイルを用意して

[01]
name=TARO
age=20

あとはこんな風に呼び出します。

        static void Main(string[] args)
        {
            var h = Ini.Read<Human>("01", "DATA.INI");

            h.age = 15;
            h.name = "JIRO";
            Ini.Write("02", h, "DATA.INI");
        }

 

実行しますと、

image

こんな感じでデータが読み出されます。

でもって、 ini ファイルは

[01]
name=TARO
age=20
[02]
name=JIRO
age=15

こんな感じに、ちゃんとセクション 02 が書き込まれます。


躓きそうなところ:

データを格納するクラスが、こういう感じに {get; set;} な状態になっている場合:

    public class Human
    {
        public string name { get; set; }
        public int age { get; set; }
    }

上記コード内の GetFields を GetProperties に換え、 FieldType を PropertyType に変えれば動作します。


・・そんなわけで、もし良ければ自己責任でご利用ください-。

Visual Studio の C++ プロジェクトでフィルタではなくフォルダを使う


お久しぶりです。みむらです。

なんだかんだ書きたいことは多々あるのですが、
書く気力と時間がどうしても・・。ごめんなさい。

 

さてさて。

image

なんだかんだで Visual Studio で C++ を用いたプログラムを書くことが多々ありまして、
その関係で一つ。

右側(Express 版だと左側の方が多いかも・・。)
にあるソリューションエクスプローラにおいて、
フォルダを追加しようと右クリックメニューの追加を見に行っても、

image

「新しいフィルター」となっており、フォルダの作成メニューではありません。
このときに、フィルタではなくフォルダを作って管理したい時にどうすればいいかという話です。

 


1.「すべてのファイルを表示」ボタンをクリックします。

image

なお、クリックすると下に示すように、
フィルタによる表示ではなくなり、ファイルツリーでの表示になります。

image

 

2.フォルダを作ります。

image

先ほどの「新しいフィルター」のメニューが、「新しいフォルダー」に変わります。


私自身は普段フィルタを使って作業していますが、
何となくフォルダでやってみたくなりまして調べてみて、
なかなか見つからなかったのでメモしました。

Visual Studio で C++ のテストをするとき、ブレークポイントを貼れない時のチェックポイント。


みむらです。

相変わらずの長々としたタイトルですが、
このブログ、主に私自身が使うので(ぁ タイトルで内容が把握できた方が都合がいいのです。
・・・RSS リーダーとかで読んでる方ごめんなさい。

今回は、某プロダクトのコードを書いている時にはまった現象。

(環境は Visual Studio 2010 にて検証。


現象:

「ブレークポイントは現在の設定ではヒットしません。このドキュメントのシンボルが読み込まれていません。」
と出て、ブレークポイントを設定しても無効になる。

具体的には、ブレークポイントを貼ったところが実行時に無効状態になり、
マウスでポイントすると、上記メッセージがでる。

 

確認箇所および修正:

Google で検索しますといろいろなサイトがヒットしますが、
それらで指示されている部分をまず確認。

要約しますと次の通り。
(引用元 : http://ameblo.jp/waka21/entry-10289918886.html

・プロパティ構成が「Debug」か。
・Debug 構成でビルドされた lib, dll を使っているか。
・リンカ設定を確認し、きちんと読み込まれるように設定されているか。
・プロジェクトプロパティの構成プロパティ –> デバッグ –> 「デバッガーの種類」が正しく設定されているか。

今回はこれらをチェックしても改善しませんでしたが、以下の設定を確認して解決しました。

プロジェクトプロパティにおいて、
構成プロパティ –> C/C++ –> コード生成 –> 「最小ビルドを有効にする」 が 「いいえ(/Gm-)」
に設定されているかどうか。

ということで、「簡易ビルド /Gm」が有効になっていると、
ブレークポイントが貼れなくなることがありますので、填まっている方は是非確認をしてみてはいかがでしょう。

IronPython を C# から使ってみる。


みむらです。

Python でさくさくっとコードを書いて実験するという人はいると思うのですが、
それを .net で応用してみようという感じの内容です。

今回は執筆時のバージョン IronPython 2.7.1 を用いて紹介します。

(本家 Python の Version 2.7.1 と多少の点は異なりますが、かなりの部分で互換性があります。)

 

1.環境準備

C# の開発環境として、今回は Visual Studio 2010 を使用します。

http://www.microsoft.com/japan/msdn/vstudio/express/
ない方は、こちらから express 版を入れておくと良いかと思います。

 

加えて、今回のメインである、IronPython を、
http://www.ironpython.net/
ここから、ダウンロードしてインストールします。

 

2.プロジェクト作成

Visual Studio を立ち上げて、プロジェクトを作成します。

image

image

Visual C# の 「コンソールアプリケーション」を作成。

 

3.参照に IronPython を追加する。

image

ソリューションエクスプローラの参照設定を右クリック –> 参照の追加

image

インストールディレクトリに移動して、

C:\Program Files\IronPython 2.7.1
or
C:\Program Files (x86)\IronPython 2.7.1

あたりにファイルがいると思います。

IronPython.dll と Microsoft.Scripting.dll を追加。

 

4.コードを書く

コードの先頭に

using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

を追記。

最小のコードとしてはこんな所でしょうか:

using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

class Program
{
    static void Main(string[] args)
    {
        ScriptEngine engine = Python.CreateEngine();
        ScriptSource src = engine.CreateScriptSourceFromString("print \"Hello Python World\"");
        src.Execute();
    }
}

5.実行

image

 

ということで、ばっちり Python コードが C# 上から実行可能です。


応用例をいくつか。

ScriptScope を定義することによって、C# 上のクラスや、他のオブジェクトを触ることも可能となります。

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

public class hoge
{
    public void call()
    {
        System.Console.WriteLine("Hello C# World");
    }
}

class Program
{
    static void Main(string[] args)
    {
        ScriptEngine engine = Python.CreateEngine();
        ScriptScope scope = engine.CreateScope();
        scope.SetVariable("hoge", new hoge());

        ScriptSource src = engine.CreateScriptSourceFromString(@"

print ""Hello Python World""
hoge.call()"
        
            );
        src.Execute(scope);
    }
}

実行結果:

image

 

上記のように、

CreateScope() メソッドで作成したスコープに対して、
SetVariable() メソッドを利用し、第1引数に名前、第2引数に実体を指定することにより、
Python 上から利用可能となります。

 

ただ一つ注意点としては、
クラスが public でないと正常に動作しないという点があります。

 

これは、個人的には Python のクラスが全て public なのが起因しているのかと予想しておりますが、
詳細はよく分かっていません。


別の例:

image

using System;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

class Program
{
    static void Main(string[] args)
    {
        ScriptEngine engine = Python.CreateEngine();

        ScriptSource src = engine.CreateScriptSourceFromString("1+2+3");
        System.Console.WriteLine("RET : " + src.Execute());
    }
}

Execute メソッドの戻り値はそのまま実行結果になっていますので、
このように結果を C# 側に返すということも可能です。

 

また、

image

このように、GetVariable メソッドを利用して値を取得することも可能です。


 

IronPython の利用例としては、
プログラム上のマクロ機能の提供が一番大きいのではと考えております。

その他には、Python でライブラリが提供されている物に対して、IronPython を通して C# から利用するというパターン。

 

今回の IronPython と同様のコールの仕方を用いることで、

http://ironruby.net/
こちらの IronRuby を利用することも可能です。

執筆時点では Version 1.1.3 ですが、これは本家の Ruby の Version 1.9.2 と互換性があると明記されています。

 

.net では同じ .net 上で動作する言語同士を協調動作させることができますので、
こういうのもアイデアによっては非常に良い物になるのではないでしょうか。

 

最後に。私が某所でやってきた時のプレゼン資料を最後に貼り付けておきます。