C, Java, C#, JavaScript, Perl などに変換可能な Ć 言語
今回は C, Java, C#, JavaScript, Perl などに変換して使う Ć 言語について紹介します。
Ć の文字
まず、 "Ć" が読めないと思います。私もよくわからないのですが、 Ć は acute(鋭い) アクセントのついた C で、 ポーランド語などのアルファベットらしいです。 読み方は "シ" っぽいです。
Unicode では U+0106 で、 HTML では Ć で表示できます。
Ć 言語とは
Ć 言語は Ć でソースを書いて、いろんな言語に変換して使うタイプの言語で、 移植性の高いライブラリーを作ることが目的です。- C 言語
- Java
- C#
- JavaScript
- ActionScript
- Perl
- D 言語
構文も C# とほとんど一緒です。
特徴
Haxe との比較
似たタイプの言語としては Haxe があります。 変換可能な言語を Haxe と比較してみます。| 言語 | Ć 言語 | Haxe | |
|---|---|---|---|
| Web (クライアントサイド) | JavaScript | ○ | ○ |
| Flash | ○ (ActionScript) | ○ (swf) | |
| Native | C 言語 | ○ | X |
| C++ | X | ○ | |
| D 言語 | ○ | X | |
| 仮想マシン(VM) | C# | ○ | △ (実験段階) |
| Java | ○ | △ (実験段階) | |
| NekoVM | X | ○ | |
| スクリプト言語 | Perl | ○ | X |
| PHP | X | ○ | |
NekoVM ではバイトコードを出力する点や Flash の生成コードなどでその特徴的がよくでていると思いますが、 Haxe の生成ファイルは人が読むことを想定していません。 それに対して Ć 言語では人が読みやすいコードを生成することが大きな違いです。
これは 2 つの思想的な違いから来ていると思います。
Haxe は Haxe さえ覚えておけば、生成言語を知らなくても、そのアプリを作れることを目的としており、 なるべく Haxe 内で完結させようとしています。
一方、 Ć 言語は特定のアルゴリズムの処理など部分的なライブラリーを作ることを目的としています。 そのためか、ファイル IO や GUI のモジュールもなく、Ć 言語だけで完結することは難しいでしょう。
Ć 言語は他の言語のラッパーであり、この辺は CoffeeScript に近いと思います。
ソースファイル
Ć 言語のソースファイルの拡張子には .ci を使用します。コメントを含めて、日本語は使用できないようです。
/// Hello class public class HelloCi { /// Calculates sum of `a` and `b`. public static int Add(int a, int b) { return a + b; } /// Return greeting string. public static string GetMessage() { return "Hello, world!"; } /// Contant sample public const string Version = "0.1"; }これを C# に変換すると次のようになります。
// Generated automatically with "cito". Do not edit. /// <summary>Hello class</summary> public class HelloCi { /// <summary>Calculates sum of <c>a</c> and <c>b</c>.</summary> public static int Add(int a, int b) { return a + b; } /// <summary>Return greeting string.</summary> public static string GetMessage() { return "Hello, world!"; } /// <summary>Contant sample</summary> public const string Version = "0.1"; }その他の言語への出力結果を含んだもう少し大きなサンプルは以下を見てください。 生成コードの読みやすさとして、次の特徴があります。
- コメントを残す
- 命名をなるべくそのまま使う
コメントのスタイルも生成言語に合わせてくれるので、 生成言語のドキュメントツールを使えば、ライブラリーのリファレンスなども生成できるようになっています。
また、この手のものは、文字に余分な文字を足したりして、シンボルの名前がかぶらないようにするものですが、 Ć 言語では、むしろ生成後の名前を予測できようにして、 生成コードとの連携をとれるようにしているようです。
インストールと使い方
インストール
ダウンロードページから最新版のバイナリーパッケージ (cito-X.X.X-bin.zip) をダウンロードします。
ダウンロードしたファイルを適当なフォルダーに展開します。
後は、環境変数 Path にそのフォルダーを追加するか、フルパスで使用します。
コンパイル(変換)
変換には cito.exe を使用します。 書式は以下の形式です。$ cito [OPTIONS] -o 出力ファイル 入力ファイル
$ cito -o hello.cs hello.ci $ cito -o HelloCi.java hello.ci出力形式は出力ファイルの拡張子で指定するか、 -l オプションで指定します。 詳細は --help オプションでヘルプを見て下さい。
標準の入出力が使えないとか -o がオプションなのに省略できないなど結構、使い勝手ににはツッコミどころが多いです。
もう一個ついてくる cipad.exe は一度に複数の言語への変換結果を表示するツールです。
おまけ的なツールなので、別に構わないのですが、こちらも使い勝手は悪いです。
Emacs の設定
残念ながら Ć 言語用の Emacs モードはまだ出ていないみたいです。(2013-06-19)ただ、 C# 用のモードを使えば、結構代用できます。
C# 用のモードはパッケージがあり、 csharp-mode という名前です。これを選択してインストールします。
インストールすると *.cs のファイルを開くと、csharp-mode になります。 *.ci のファイルでも csharp-mode になるように ~/.emacs.d/init.el に以下の記述を追加します。
;; Ć 言語 (add-to-list 'auto-mode-alist '("\\.ci$" . csharp-mode))C# 用で便利なように csharp-mode ではコメントで "/" を押したときに <summary> などを自動的に追加する機能があります。 これは Ć ではちょっと邪魔になります。
次の記述も追加すると、 *.ci では追加しないようになります。
(add-hook 'csharp-mode-hook '(lambda () (if (string-match "\\.ci$" buffer-file-name) (local-set-key "/" 'c-electric-slash))))また、 M-x compile でコンパイルした時、 cito のコンパイルエラーはエラー行をうまく認識してくれません。
以下の記述も追加するとエラー行を認識してジャンプ等ができるようになります。
(require 'compile) (setq compilation-error-regexp-alist (append '(;; hello.ci(3): ERROR: Expected Id, got Slash ("^\\([^(]+\\)(\\([0-9]+\\)): \\(\\w+\\):" 1 2 3)) compilation-error-regexp-alist))
感想
マルチ言語への変換としてみた場合、 Haxe と比べると Ć 言語は小粒です。 ただ、 生成コードの読みやすさなど、CoffeeScript のように軽いラッパーにはラッパーの良さもあります。ただ、ライブラリーが全然ないのは、用途が限定されすぎてしまいます。 GUI は難しいとしても、 ファイル IO 、コレクションクラス、 点や矩形のような図形クラスといった基本的なもの欲しいところです。
JavaScript への変換だけを見れば、 "JavaScript はよく知らないけど、 C# はいつも使っている"という人にはいいかもしれません。 それでも、やっぱりライブラリーの機能は欲しいですが。
できたばかりの言語で、全体的にまだまだといった印象です。 ただ、狙いは面白いので、これからに期待したい言語です。
Windows でも意外と役立つ gzip 圧縮を C# から使う
gzip といっても Windows ではなじみがない人が多いでしょう。
しかし、 gzip は意外と使えるヤツです。 しかも .NET では gzip の 圧縮、展開を行うのに便利なクラスが用意されています。
そこで今回は Windows でも意外と役に立つことを紹介した後、 C# での gzip の圧縮、展開方法を説明したいと思います。
gzip とは
gzip は GNU ZIP の略で、 gzip という圧縮コマンドやその圧縮方式(圧縮後の拡張子は .gz) を指します。 Unix 系ではよく使われている圧縮方式です。一方 Windows では ZIP がよく利用されています。 gzip と ZIP はともに Deflate という圧縮アルゴリズムを使用します。 ただし、ZIP は複数ファイルをまとめる機能を持っているのに対して、 gzip は単にデータ(ファイル)を圧縮するためのものです。 このため、ファイルをまとめる機能を持つ tar と合わせて(.tar.gz、 .tgz)使用されることが多いです。
なお、 .NET 4.5 であれば、 ZIP の圧縮、展開も対応したらしいです。 ただし、 私の場合は Windows 7 、 .NET 4.5 、 VS2012 Express の環境でやっていみたのですが、 ZIP 用のクラスは使えませんでした。
gzip の用途
先ほどの説明だと単に gzip の機能が ZIP に比べて劣っているという印象を受けた人もいるかもしれません。 確かに ZIP は便利だし、よく使われていますが、 シンプルなものにはシンプルなりの用途があります。通信データの圧縮
gzip コマンドを使ったことがないという人は多いかもしれませんが、 実はかなりの人が知らない間に gzip 圧縮を利用しています。というのも、見かけ上はわからないようになっていますが、 HTTP 通信で gzip 形式の圧縮がよく使われているためです。
使われる場合は次のような手順です。
- サーバー上には *.html.gz, *.css.gz といった圧縮したファイルを置く
- ブラウザーが対応していれば、 圧縮されたまま通信 (最近のブラウザーはほとんど対応)
- 対応してない場合はサーバーで展開
- ブラウザー側で展開して表示
通信相手が Windows でない場合でも、そちらは zlib などを使えば、 圧縮、展開は結構簡単に実装できます。
ファイルフォーマット
アプリケーションを作成した場合などで、独自フォーマットのファイルを作ることはあるでしょう。この時、陥りやすいトラップが "ビットレベルで詰めたら、サイズが得になっていいのではないか" という考え方です。
これは間違いではないのですが、実装がかなり大変になる上に、 たいていは効果も薄いです。
それをやるくらいなら、作りやすいフォーマットにして、全体または部分的にデータを圧縮した方が、 作成者にも使用者にも嬉しいフォーマットになります。
実際に svgz や PNG などでは、そうやって gzip(Deflate) が使われています。
使用クラス
データ圧縮、展開用のクラスとしては DeflateStream と GZipStream の 2 つのクラスがあります。
gzip も Deflate アルゴリズムなので、 DeflateStream と GZipStream はほとんど同じものです。
ただし、 GZipStream の方が 2 つ利点があります。
- データ破損を検出するための巡回冗長検査 (CRC) 値を含んでいる
- 拡張して Deflate 以外のアルゴリズムに変更することができる
これをフィルターのように入出力のストリームの間にかませることによって、 圧縮・展開を行うことができます。
ちなみに Unix でも gzip コマンドはフィルターとしてよく使われています。
実装
引数に渡すファイルによって次のような動作するコマンドラインプログラムをサンプルとして作ってみました。| 引数 | 動作 |
|---|---|
| .gz で終わるファイル | 展開 |
| .gz 以外のファイル | 圧縮 |
ソースファイル : コンパイル:
> csc GZipSample.cs実行結果 :
~/cs/gzip $ ./GZipSample.exe sample.txt Input : sample.txt Compress : sample.txt.gz ~/cs/gzip $ ls GZipSample.cs GZipSample.exe sample.txt sample.txt.gz ~/cs/gzip $ rm sample.txt ~/cs/gzip $ ls GZipSample.cs GZipSample.exe sample.txt.gz ~/cs/gzip $ ./GZipSample.exe sample.txt.gz Input : sample.txt.gz Decompress : sample.txt ~/cs/gzip $ ls GZipSample.cs GZipSample.exe sample.txt sample.txt.gz
以下に圧縮、展開の処理部分を GZipStream.cs から抜粋したものをあげます。
なお、
using に関して詳しく知りたい方は以前の記事を参考にしてください。
圧縮 :
public static void GZipCompress(string srcpath, string gzpath) { // 入力用ストリーム using (FileStream fin = new FileStream(srcpath, FileMode.Open, FileAccess.Read, FileShare.Read)) { // 出力用ストリーム using (FileStream fout = File.Create(gzpath)) { // 出力用ストリームに gzip ストリームのフィルターを付ける using (GZipStream gzout = new GZipStream(fout, CompressionMode.Compress)) { fin.CopyTo(gzout); } } } }展開 :
public static void GZipDecompress(string gzpath, string destpath) { // 入力用ストリーム using (FileStream fin = new FileStream(gzpath, FileMode.Open, FileAccess.Read, FileShare.Read)) { // 出力用ストリーム using (FileStream fout = File.Create(destpath)) { // 入力用ストリームに gzip ストリームのフィルターを付ける using (GZipStream gzin = new GZipStream(fin, CompressionMode.Decompress)) { gzin.CopyTo(fout); } } } }GZipStream はストリームとして実装されているのが、よくできている点だと思います。
サンプルではファイルのストリームでしたが、 Stream を継承したクラスであれば、同じようにフィルターとして使うことができます。
通信部分をNetworkStream クラスを使って実装していれば、 圧縮したデータによる通信機能も簡単に追加することができるのではないかと思います。
WPF での文字列リソースの利用と国際化
今回は WPF で文字列リソースを使う方法と国際化に関する記事です。
WPF では、文字列リソースを使ってアプリケーションを作っておけば、簡単に国際化することができます。ここで "文字列リソースを使う"といっているのは、文字列をリソースファイルにまとめて定義し、 それを WPF のラベルやコード内のメッセージに使うことを意味しています。
"国際化する予定はない"という場合も多いとは思います。 その場合でも、コード内に文字列を直接書くのはあまり良くないので、 リソースを使ったコードと文字列の分離だけはやっておいた方がいいでしょう。
これから、サンプルアプリの作成手順にあわせて、リソースの利用法と国際化について説明していきたいと思います。
国際化の方法については以下のサイトを参考にさせて頂きました。参考というよりほぼ一緒ですが、ちょっと視点を変えて解説したつもりです。
文字列リソースの使用
最初はまだ国際化せずに、文字列リソースを利用しただけのアプリケーションを作成することにします。まず "WpfI18n" という名前で [WPF アプリケーション] を新規作成します。
初期の構成は次のようになっています。
リリースファイルの登録と作成
リソースファイルを使えるようにするためには、 App.xaml にリソースを登録する記述を追加します。App.xaml :
<Application x:Class="WpfI18n.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:properties="clr-namespace:WpfI18n.Properties" StartupUri="MainWindow.xaml"> <Application.Resources> <properties:Resources x:Key="resources" /> </Application.Resources> </Application>Resources.resx がリソースファイルです。これを編集して文字列リソースを定義していきます。
国際化時のデフォルトの文字列とするので、英語版で作成します。

アクセス修飾子は Public を指定します。
ここでいったんビルドを行なって下さい。リソースを編集した場合、ビルドしていないと選択時の候補などが更新されないことがあります。
レイアウト
MainWindow のサイズを適当に変更し、ボタンを一つ配置します。 名前はbuttonGreet としておきます。
サンプルなのでてきとうですが、実際に国際化するには Panel などのコントロールを利用して、 サイズや位置を直接指定しないようにする必要があります。 Qt, Gtk+ といった Unix 系のツールキットでは、伸縮を考慮したレイアウトの方が普通です。
Windows ではようやく WPF からちゃんと対応しました。 しかし、 VS の GUI ビルダーでは勝手にサイズなどをいれてしまうため、 いちいち [リセット] していく必要があります。 この辺はもう一息といったところです。
UI からのリソース利用
[Content](表示内容)を文字列で直接入力するのではなく、 データバインドを利用する ところがポイントです。サンプルでは、ボタン(buttonGreet)とウィンドウのタイトルを文字列リソースで指定しています。
Content のところでデータバインドを設定するダイアログを開きます。
ここで [StaticResource] を選び、各リソース名を選択します。
VS2010 の場合はちょっとわかりづらいですが、 [ソース] で [StaticResource]、 [Application.Resources]と順に選択してから、[パス]で各リソース名を選択します。
コードからのリソース利用
コードから文字リソースを利用する例も挙げておきます。ボタン(buttonGreet) をダブルクリックして、コールバック用のメソッドのひな形を追加します。 そこに以下の記述を追加すれば、 buttonGreet を押すと文字列リソースで定義されたメッセージを表示するようになります。
MainWindow.xaml.cs :
private void buttonGreet_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(Properties.Resources.MessageHello);
}
ここでビルドして、実行してみてください。
文字列リソースで定義した文字がアプリケーションで使用されていることが確認できると思います。
国際化
リリースファイルの作成
次の手順で、[ソリューション エクスプローラー] の操作を行い、日本語の文字列リソースファイルを作成します。- Resources.resx をコピー
- プロジェクトに対して貼り付け
- Resources.ja-JP.resx と名前を変更
- [Properties] に移動

作成したリソースファイルを開き、値を日本語に変更します。 このときアクセス修飾子は [コード生成なし] にします。

ビルドして、実行してみてください。これだけで日本語に変更されているはずです。
リリースファイルの仕組み
英語で表示されていた場合の仕組みは次のようになっています。- ユーザーの設定は 言語:日本語(ja)、地域:日本(JP)
- ja-JP のリソースを探す
→ みつからない - デフォルト(Resources.resx)のリソースを使用
- 英語で表示
"ja-JP" というのは、 言語、地域を指定する Culture 名です。どのよう文字を指定するかは以下のサイトで確認できます。
- CultureInfo クラス (System.Globalization) [.Net Framework 2.0]
- National Language Support (NLS) API Reference
例えば、 日本語のリソース定義が足りていなかったとしたら、どうなるでしょうか?
この場合はその文字だけデフォルト(英語)のリソースが使用されます。
このように文字列リソースはファイル、項目などが見つからない場合にはデフォルトが使われます。 日本語をデフォルトにしていると英語環境では文字化けする危険があります。 デフォルトは英語 の方がいいでしょう。 (逆に英語が混じっていても、まずバグとは言われません)
なお、リソースファイル(.resx)の実態は XML フォーマットのテキストファイルです。
テキスト差分表示のツールなどで対応を確認することもできます。
生成ファイル
日本語用の文字列リソースファイルを作ってビルドすると、 exe のところに次のようなファイルも生成されます。リリースする場合にはこの構成でリソース用の dll を付けてリリースしてください。
(Debug|Release)/
├ WpfI18n.exe
└ ja-JP/
└ WpfI18n.resources.dll
国際化のテスト
日本語のリソースを作成したら、日本語で表示されるのはいいのですが、 今度は英語が表示できません。表示言語を切り替えて、各言語での表示を確認する方法について説明します。ちなみに、 英語と日本語だけでいいということであれば、"ja-JP" のフォルダーを削除すれば、 英語で表示することも可能です。
ユーザー環境の変更
言語、地域はユーザーごとに設定します。これは [コントロールパネル] から変更することができます。
コントロールパネルの表示スタイルによっても変わりますが、 [表示言語の選択] や [地域と言語] の項目を選択すると、 ダイアログが表示されます。 ここで表示言語を変更します。

ただし、他言語が一つもインストールされていないと選択項目は表示されません。 インストールできるかどうかは OS のタイプ(Ultimate など)によります。

言語の設定を反映させるにはログオフをする必要があります。 ちゃんとテストする場合などはテスト用のユーザーを作り、 それを切り替えて確認することになるかと思います。
ただし、開発中の確認などではそれも面倒です。 次節で起動時にプログラムの表示言語を変える方法を説明します。
こちらは他言語がインストールされていなくても表示することができます。
起動時に表示言語を変えるコードを加える
次の方法でカルチャー名を指定して起動できるような修正を行います。- 環境変数
- コマンド引数
さらに改造すれば、ファイルから読み取ったり、保存していた設定(次回の起動時から有効)で指定したり といったこともできるのではないかと思います。
起動時に実行するメソッドを追加
アプリケーションの XAML にStartup の要素で起動時に実行するメソッドを追加します。App.xaml :
<Application x:Class="WpfI18n.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:properties="clr-namespace:WpfI18n.Properties" StartupUri="MainWindow.xaml" Startup="Application_Startup"> <Application.Resources>VS 上で追加すれば、関数名やコードへのひな形も自動的に追加されます。
:
カルチャー情報の変更
追加した起動時のメソッドで現在のスレッドのカルチャー情報を変更します。GUI の表示を変えるため、
CurrentCulture ではなく CurrentUICulture
になっているところに注意してください。App.xaml.cs :
private void SetCurrentUICulture(string culname)
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culname);
}
private void Application_Startup(object sender, StartupEventArgs e)
{
// 環境変数を使用
string langstr = System.Environment.GetEnvironmentVariable("TEMP_LANG");
if (langstr != null)
{
SetCurrentUICulture(langstr);
}
// 引数を使用
if (0 < e.Args.Length)
{
SetCurrentUICulture(e.Args[0]);
}
}
スレッドやカルチャー情報を使うための名前空間も追加する必要があります。
using System.Threading; // 追加 using System.Globalization; // 追加
実行
次のように引数を指定して実行すると、英語版画面が表示されます。 ~/cs/i18n/WpfI18n $ ./bin/Debug/WpfI18n.exe en-US
ただし、サンプルでは en-US のリソースを表示しているわけではありません。
en-US のリソースがないため、デフォルトのリソースを使用した結果、英語版で表示されています。
サンプルコード
作成したサンプルアプリのコードもあげておきます。 なお、サンプルを順に作らずに、サンプルコードをそのままビルドして実行すると XAML の解析で実行時例外が発生する時があります。この場合、 改行を足すなど、なんでもいいので、MainWindow.xaml.cs ファイルをちょっと修正して、ビルドしなおすと解消することが多いです。 私も原因はよくわかってないのですが...
Home
Title list
RSS
Admin






