Code Snippet With Syntaxhighlighter を使ってみる

【WindowsLiveWriter】で「Code Snippet With Syntaxhighlighter」を使ってソースコードを入力する | Q-miz blog(きゆみずぶろぐ) の記事を参考にして、Windows Live Writer でコードを書いてみるテスト。このブログ自体、SyntaxHighlighter は入っているのだけど、いつもは QX エディタで編集、自前 Perl スクリプトで整形、自前アップロードプログラムで WordPress へ投稿、ってなことをやっている。コードの編集とか画像の縮小とかを自動化しているんだけど、単なる文章の場合は Windows Liver Writer で書くことが多い。

Xamarin.iOS 拡張を見ると、Visual Studio拡張がどうやっているのか調べる必要があって GUID を頼りにレジストリエディタをのぞいてみると、

[HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio12.0_ConfigProjects{6bc8ed88-2882-458c-8e55-dfd12b67127b}]
@="MonoTouchProjectFactory"
"DisplayName"="Xamarin.iOS"
"DisplayProjectFileExtensions"="Xamarin.iOS Projects (*.csproj);*.csproj"
"Package"="{77875fa9-01e7-4fea-8e77-dfe942355ca1}"
"ProjectTemplatesDir"="\..\NullPath"
"Language(VsTemplate)"="CSharp"
"ShowOnlySpecifiedTemplates(VsTemplate)"=dword:00000001
"TemplateGroupIDs(VsTemplate)"="MonoTouch"
"TemplateIDs(VsTemplate)"="Microsoft.CSharp.XmlFile,Microsoft.CSharp.TextFile,Microsoft.CSharp.CodeFile,Microsoft.CSharp.Class,Microsoft.CSharp.Resource,Microsoft.CSharp.AssemblyInfo.Internal"

 

こんなところのプロジェクトテンプレートがある。 このパッケージ 77875fa9-01e7-4fea-8e77-dfe942355ca1 をもう一度検索すると、

[HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio12.0_ConfigPackages{77875fa9-01e7-4fea-8e77-dfe942355ca1}]
@="MonoTouchPackage"
"InprocServer32"="C:\Windows\SYSTEM32\MSCOREE.DLL"
"Class"="Mono.IOS.VisualStudio.MonoTouchPackage"
"CodeBase"="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Xamarin\Xamarin.iOS\1.10.47.0\Mono.IOS.VisualStudio.dll"

 

なところで、DLLを定義していることがわかる。

この部分で CSharp プロジェクトテンプレートを VisualBasic テンプレートに切り替えるのか?と思っているのだけど、いやいや、FSharp の場合は別だろうから、Visual Basic拡張は別途作らないといけないかも、後で調べよう。

カテゴリー: Wordpress, Xamarin | Code Snippet With Syntaxhighlighter を使ってみる はコメントを受け付けていません

Visual Basic で iOS アプリを書くプロジェクトを作成…できた

Visual Basic で iOS アプリを書くプロジェクトを作成…している途中 | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/5604

昨日の続きで、Xamarin.iOSを使ってVBでコードを書いてiOSアプリを書く、というニッチな話を。
結論から言うと、一応できました。結構、回避策を使っているので、もうちょっとアプローチを考えないといけないのですがブレイクスルーはできた感じ。

■Xamarin.MonoTouch.VisualBasic.targets を作成する

以下の3つのファイルを作成します。

C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.MonoTouch.VisualBasic.targets

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<PropertyGroup>
		<TargetFrameworkIdentifier>MonoTouch</TargetFrameworkIdentifier>
		<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v1.0</TargetFrameworkVersion>
	</PropertyGroup>
	<Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.Targets" />
	<Import Project="Xamarin.MonoTouch.Common.targets" />
</Project>

C:\Program Files (x86)\MSBuild\Xamarin\Xamarin.ObjcBinding.VisualBasic.targets

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.ObjcBinding.VisualBasic.targets" />
</Project>

C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.ObjcBinding.VisualBasic.targets

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <UsingTask TaskName="Xamarin.ObjcBinding.Tasks.BTouch" AssemblyFile="Xamarin.ObjcBinding.Tasks.dll" />

  <PropertyGroup>
    <TargetFrameworkIdentifier>MonoTouch</TargetFrameworkIdentifier>
    <TargetFrameworkVersion Condition="'$(OS)' == 'Unix'">v1.0</TargetFrameworkVersion>
    <TargetFrameworkVersion Condition="'$(OS)' != 'Unix'">v4.0</TargetFrameworkVersion>
  </PropertyGroup>

  <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.Targets" />
  <Import Project="Xamarin.ObjcBinding.Common.targets" />

  <PropertyGroup>
    <!-- work around a bug in the Mono Microsoft.CSharp.Targets that defaults the compiler to gmcs -->
    <CscToolExe Condition = "'$(OS)' == 'Unix'">vbnc</CscToolExe>

    <!-- Btouch needs CscPath, but when building from within Visual Studio, it and the CscTool{Exe,Path}
         properties will be empty since VS uses the in-process compiler, so fix them. -->
    <CscPath Condition="'$(CscPath)' == '' And '$(OS)' != 'Unix'">$(CscToolPath)$(CscToolExe)</CscPath>
    <CscPath Condition="'$(CscPath)' == '' And '$(OS)' != 'Unix'">$(MSBuildToolsPath)\vbc.exe</CscPath>

    <BaseLibDllPath Condition="'$(OS)' == 'Unix'">/Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll</BaseLibDllPath>
    <BaseLibDllPath Condition="'$(OS)' != 'Unix'">$(MSBuildExtensionsPath)\Xamarin\iOS\monotouch.dll</BaseLibDllPath>
    <BTouchToolExe Condition="'$(BTouchToolExe)' == '' And '$(OS)' == 'Unix'">/Developer/MonoTouch/usr/bin/btouch</BTouchToolExe>
    <BTouchToolExe Condition="'$(BTouchToolExe)' == '' And '$(OS)' != 'Unix'">$(MSBuildExtensionsPath)\Xamarin\iOS\btouch.exe</BTouchToolExe>
    <GeneratedSourcesFileList Condition="'$(GeneratedSourcesFileListing)' == ''">$(GeneratedSourcesDirectory)\sources.list</GeneratedSourcesFileList>
  </PropertyGroup>

  <!-- Add our own pre-build steps -->
  <PropertyGroup>
    <CompileDependsOn>
      GenerateBindings;
      $(CompileDependsOn)
    </CompileDependsOn>
  </PropertyGroup>

  <!-- Override the CoreCompile Target to use btouch -->
  <Target Name="GenerateBindings"
  	  Inputs="$(MSBuildAllProjects);@(ObjcBindingApiDefinition);@(ObjcBindingCoreSource);@(ReferencePath);@(ObjcBindingNativeLibrary)"
	  Outputs="$(GeneratedSourcesFileList)">

    <BTouch AdditionalLibPaths="$(AdditionalLibPaths)"
    	    AllowUnsafeBlocks="$(AllowUnsafeBlocks)"
	    ApiDefinitions="@(ObjcBindingApiDefinition)"
	    CoreSources="@(ObjcBindingCoreSource)"
	    DefineConstants="$(DefineConstants)"
	    GeneratedSourcesDirectory="$(GeneratedSourcesDirectory)"
	    GeneratedSourcesFileList="$(GeneratedSourcesFileList)"
	    Namespace="$(Namespace)"
	    BTouchToolPath="$(BTouchToolExe)"
	    CompilerPath="$(CscPath)"
	    BaseLibDll="$(BaseLibDllPath)"
	    NoStdLib="$(NoStdLib)">
      <Output TaskParameter="GeneratedSourcesFileList" ItemName="GeneratedSourcesFileList" />
    </BTouch>

    <ReadLinesFromFile File="$(GeneratedSourcesFileList)" >
      <Output TaskParameter="Lines" ItemName="GeneratedSources" />
    </ReadLinesFromFile>

    <CreateItem Include="@(ObjcBindingCoreSource)">
      <Output TaskParameter="Include" ItemName="Compile" />
    </CreateItem>

    <CreateItem Include="@(GeneratedSources)">
      <Output TaskParameter="Include" ItemName="Compile" />
    </CreateItem>

    <CreateItem Include="@(ObjcBindingNativeLibrary)">
      <Output TaskParameter="Include" ItemName="ManifestResourceWithNoCulture" />
    </CreateItem>
  </Target>

</Project>

■*.sln と *.vbproj を書き換える

どうやら、mac にデプロイしていなさそうの勘はあたりで、デプロイ(配置)するようにしたら通りました。
*.sln に以下になるように追加。「Deploy.0」が配置の実行にあたります。91DDFB1F-30BD-472E-9022-0D0E29A8A301 は VB プロジェクトの GUID です。

{91DDFB1F-30BD-472E-9022-0D0E29A8A301}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{91DDFB1F-30BD-472E-9022-0D0E29A8A301}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{91DDFB1F-30BD-472E-9022-0D0E29A8A301}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator

*.proj のほうは、以下になるように書き換えます。ProjectTypeGuids はプロジェクトの種類を設定するもので、6BC8ED88-2882-458C-8E55-DFD12B67127B は、Xamarin.iOS の C# の GUID です。このままだと C# のコンパイラが走ってしまうのでコメントアウトしています。が、このコメントを消してしまう(ProjectTypeGuids自体を削除する)とデプロイできません。変ですね(苦笑)。まあ、*.vbproj の読み込み部分が変らしいので、これはこれで使わせてもらいます。

<ProjectGuid>{91DDFB1F-30BD-472E-9022-0D0E29A8A301}</ProjectGuid>
<!--
<ProjectTypeGuids>{6BC8ED88-2882-458C-8E55-DFD12B67127B};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}</ProjectTypeGuids>
-->

ここに出てくる GUID は、*.sln の上のほうにある Project 部分に対応します。

Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "HelloVB", "HelloVBHelloVB.vbproj", "{91DDFB1F-30BD-472E-9022-0D0E29A8A301}"
EndProject

ProjectGuid 関連はこちらへ。おそらく、Visual Basic 用のGUIDを自作すればOKかと思います。

VSの「プロジェクトの種類がこのインストールでサポートされていません」(ProjectTypeGuids) – あおきのTechメモ
http://d.hatena.ne.jp/aoki1210/20090912/p1
INFO: List of known project type Guids
http://www.mztools.com/Articles/2008/MZ2008017.aspx

■Microsoft.VisualBasic.dll を外す

先の方法で、無事 mac へのデプロイはできたのですが、こんどは VisualBasic.dll がロードできなくて iOS シミュレータを立ち上げる前にこけます。具体的には Visual Studio に出てくる出力をみると、以下な感じで、何かが load できていません。

Loaded assembly: /Users/masuda/Library/Caches/Xamarin/mtbs/builds/HelloVB/91ddfb1f-30bd-472e-9022-0d0e29a8a301/assemblies/HelloVB.exe
2014-03-25 03:06:09.981 HelloVB[9011:70b] Could not load 'HelloVB' for registration: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/Assembly.cs:351
  at MonoTouch.Registrar.OldDynamicRegistrar.RegisterAssembly (System.Reflection.Assembly a) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/OldDynamicRegistrar.cs:67
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Xml.dll [External]
2014-03-25 03:06:09.983 HelloVB[9011:70b] This could be due to an outdated assembly kept by the simulator, location: /Users/masuda/Library/Caches/Xamarin/mtbs/builds/HelloVB/91ddfb1f-30bd-472e-9022-0d0e29a8a301/assemblies/HelloVB.exe
Missing method SetProjectError in assembly /Users/masuda/Library/Caches/Xamarin/mtbs/builds/HelloVB/91ddfb1f-30bd-472e-9022-0d0e29a8a301/assemblies/HelloVB.exe, type Microsoft.VisualBasic.CompilerServices.ProjectData
An unhandled exception occured.

多分、C# にない VisualBasic.dll を参照していると思われるので、*.vbproj から以下の設定で VisualBasic.dll を参照しないようにします。

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
...
	<NoVBRuntimeReference>true</NoVBRuntimeReference>
  </PropertyGroup>

VBなのに VisualBasic.dll を参照しないので、いくつか VB 特有の機能が失われますが、ひとまず。
VisualBasic.dll を参照していないので、My Project 回りの *.vb でコンパイルエラーが出るので、コメントアウトしていまいます。

■デバッグ実行する

うまくできると、こんな風にデバッグ実行ができます。

■サンプルはこちら

Xamarin の Hello World を VB に直したサンプルです。先の *.targets ファイルも入っています。

http://1drv.ms/1jnqkR7

VisualBasic.dll を外してしまったために、VB 特有の関数が使えなくなっています。ですが、mono にも vbnc という VB コンパイラがあるので、VisualBasic.dll はあるハズなんですよね。そのあたりをうまく整合性をあわせてやれば、もうちょっと汎用性がある形でできると思うのですが。このあたりは、Android版を作りながら考える予定。

追記 2014/03/26
プロジェクトテンプレートにしてみました。

http://1drv.ms/1l0Ssqs

カテゴリー: VB, Xamarin | Visual Basic で iOS アプリを書くプロジェクトを作成…できた はコメントを受け付けていません

Visual Basic で iOS アプリを書くプロジェクトを作成…している途中

Xamarin では C# で iOSアプリを作れるのですが、Visual Basic では作れません…が本当のか?と思って試している途中。

こんな風に、C# のプロジェクトを真似て Visual Basic でプロジェクトを作ります。

image

  1. 参照設定で、monotouch, System, System.Core, System.Xml を入れる。
  2. <Import Project=”$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.MonoTouch.VisualBasic.targets” /> を *.vbproj に追加する。
  3. C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.MonoTouch.VisualBasic.targets を新しく作成する。

中身はこんな感じ。

<Project DefaultTargets=”Build” xmlns=”http://schemas.microsoft.com/developer/msbuild/2003″>
    <PropertyGroup>
        <TargetFrameworkIdentifier>MonoTouch</TargetFrameworkIdentifier>
        <TargetFrameworkVersion Condition=”‘$(TargetFrameworkVersion)’ == ””>v1.0</TargetFrameworkVersion>
    </PropertyGroup>
   
    <Import Project=”$(MSBuildBinPath)\Microsoft.VisualBasic.Targets” />
    <Import Project=”Xamarin.MonoTouch.Common.targets” />
</Project>

  1. Settings.Designer.vb の中身はビルドができないのでコメントアウト

なところまで作ると、Xamarin.iOS を入れた状態で、Visual Basic の iOS プロジェクトがビルドできます。

…が、ビルドはできるものの、デバッグ/デプロイができない。

image

monotouch.dll が見当たらないのか、依存が見つからないのかわからないけど、必要なアセンブリがみつからない。C# のプロジェクトのでは正常にデバッグ実行できるので、Visual Basic で作ったときだけ何かが足りない。残念。

調べてみたい方は、リンクからどうぞ。

http://1drv.ms/1jhTWiG

カテゴリー: VB, Xamarin | 2件のコメント

MVP Community Camp 2014 で発表しました。

Xamarinで作るiPhoneとwindowsストアアプリの共通コンポーネント

Xamarin.iOS, Xamarin.Android を使ったデモをさらっと。サンプル用に作ったプログラム(実は、書籍用に作っているプログラム)は、あえてコードの説明を避けたのですが…まあ、コードも公開してしまいます。まだ途中なので。完成したあかつきには購入をご検討ください。たぶん、サンプルコードはフリーでダウンロードできるようになると思います。

http://1drv.ms/1g1WE9M

こんな感じのプロジェクト構成になっています。

image

カテゴリー: C#, Xamarin | MVP Community Camp 2014 で発表しました。 はコメントを受け付けていません

PCL のターゲットフレームワークに Xamarin をインストールせずに Xamarin.Android を追加する

からの一連のところの話と、明後日発表をするので、ちょっと気になったので PCL の作りを再チェックしてました。

image

Xamarin拡張を入れると、ポータブルクラスライブラリを作るときに、Xamarin.Android と Xamarin.iOS のチェックを入れられるようになるんですが、これって何処で設定しているんでしょうね?という疑問です。

そもそも、ポータブルクラスライブラリ自体は「ポータブル」なんだから、他の特殊なアセンブリを参照する必要はないんですよね。最低限のアセンブリを使うわけだから。だから、Xamarin.Androidなどのインストールをしなくても、何等かの設定で読み込めるわけで、この設定自体は何処かにあったのか…それとも Xamarin.Androidをインストールしたときか?という推測が成り立ちます。

PCLのプロジェクトをエディタで開くと、

<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile>Profile78</TargetFrameworkProfile>

となって TargetFrameworkProfile が「Profile78」になっています。これが何処にあるかというと、C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETPortable/v4.5/Profile/ フォルダの中にあるんですね。更に、SupportedFrameworks フォルダを調べると、Xamarin.Android などがあります。

image

フォルダ名は、

  • Profile7
  • Profile49
  • Profile78

と3つある訳ですが、これが何を意味するのかは他の SupportedFrameworks フォルダを覗くと分かります。

Profile7 Profile49 Profile78
.NET Framework 4.5
Windows Store apps (Windows 8).
Windows Phone 8
Xamarin.Android
Xamarin.iOS

どうやら先のチェックボックスと対応しているようです。RedistList フォルダの中には、対応するアセンブリのリストがあるので、その差分を取ってみると。

Profile7 Profile49 Profile78
Microsoft.VisualBasic
System.Threading.Tasks.Parallel
System.Reflection.Emit.ILGeneration

だいたい、こんな感じになってます。で、このProfileフォルダは Xamarin を入れたときに出来るのではなくて、最初に Visual Studio を入れたときに作られます。つまり、あらかじめ PCL となるアセンブリの組み合わせは決まっているということですね。となると、動的コード生成で使われる System.Reflection.Emit.ILGeneration は Windows ストアアプリにときに入らない、ってことになります。

このあたり、Xamarin.iOS では動的コード生成ができないという制限があるのですが、そもそもが WinRT の場合は動的コード生成ができないので、PCL にするとそもそも動的コード生成はできないってことですよ。これはMSDNにもあります。

と、今気が付いたんですが、そうなると Profile49 の Xamarin.iOS の設定って間違っているんじゃないか?と思ったり。

■Xamarin.Android を入れずに、PCL の設定で Xamarin.Android を表示するには

ってことで、ややこしいですが、

Xamarin.Android.xml

<?xml version="1.0" encoding="utf-8"?>
<Framework DisplayName="Xamarin.Android" Identifier="MonoAndroid" Profile="*" MinimumVersion="1.0" MaximumVersion="*" />

Xamarin.iOS.xml

<?xml version="1.0" encoding="utf-8"?>
<Framework DisplayName="Xamarin.iOS" Identifier="MonoTouch" Profile="*" MinimumVersion="1.0" MaximumVersion="*" />

を、対応する Profile フォルダに保存すれば OK です。Xamarin Studio をインストールしなくてもxml ファイルを作るだけです。Visual Studioを再起動すると設定が反映されます。

こんな風に OreOre.Framework を PCL に追加することもできますね。意味ないけど。

image

カテゴリー: Xamarin | PCL のターゲットフレームワークに Xamarin をインストールせずに Xamarin.Android を追加する はコメントを受け付けていません

アリスはカンマとコンマを区別する

久々のアリプラシリーズです。

元のコードはc++なんですかね?と思って自分でコードを書いてみます。ええと、カンマ(コンマ)「,」演算子は、マクロでは使うけど演算子のオーバーロードをすると関数の引数とややこしくなるわけですが、「爽やかなコード」になるかどうかは分かりません。
確か、,演算子は優先度が一番低いから、そのあたりも含めて使うといいかも。

int x , y ;
int z = (x=10,y=20);

最後の式の値を返すので、zの値は20になりますね。そのあたりを利用したマクロが量産される訳ですが。バッドテクニックと言えなくもないし広域に使うとまずそうだけど、局所的にたまに使います。データ加工したいときとか。

さて、アリスとロリータをカンマで繋ぎます。繋ぐ方法はいろいろあるので、いくつか試してみたのがこれ。どこでどうやってつながっているのかを理解するには、c++ の構文解析を「想像」する必要がありますよね。関数の引数で使うカンマと、オーバーライドできるカンマ演算子がまぜこぜになっているので、こんな感じになります。
“Alice”と”Lolita”をカンマでつなげるカンマ演算子の定義です。

#include "stdafx.h"
#include <string>
#include <iostream>

using namespace std;
std::string operator , (std::string &l, std::string &r)
{
	cout << "in operator , " << endl;
	std::string s;
	s.append(l);
	s.append(",");
	s.append(r);
	return s;
}
std::string comma(std::string &l, std::string &r)
{
	cout << "in comma function 2 arguments " << endl;
	std::string s;
	s.append(l);
	s.append(",");
	s.append(r);
	return s;
}

std::string comma(std::string &l)
{
	cout << "in comma function 1 argument " << endl;
	return l;
}

int _tmain(int argc, _TCHAR* argv[])
{
	string s1 = "Alice";
	string s2 = "Lolita";
	std::cout << "ans: " << (s1, s2) << std::endl;
	std::cout << "ans: " << comma(s1, s2) << std::endl;
	std::cout << "ans: " << comma((s1, s2)) << std::endl;
}

■実行結果

in operator ,
ans: Alice,Lolita
in comma function 2 arguments
ans: Alice,Lolita
in operator ,
in comma function 1 argument
ans: Alice,Lolita

ちなみに、「カンマ演算子」なのか「コンマ演算子」なのかは諸説あるところで、わたくし的には「テクスト」と「テキスト」の違いを意識して(「コンテクスト」と「コンテキスト」とかも)、用語定義の哲学っぽく「カンマ演算子」という呼び名が好みです。そうそう、小数点の扱いも「ポイント」は「.」だったり「,」だったりする訳で、呼び名(発声)と現物(意味)とは違うよねという話。シニフィアンとシニフィエを久し振りに。

カテゴリー: C++ | アリスはカンマとコンマを区別する はコメントを受け付けていません

Xamarinで C# interactive を動かそう…としたが無理でした

Visual Studio 2013 には F# interactive というインタープリタ版の F# コマンドラインツールがあります。これを使うと、数値の計算とかコードの検算とかが楽なので便利に使っているのですが、Xamarin Studio にも F# interactive があります。

Xamarin Studio で「ビュー」→「パッド」→「F# interactive」で開くと、文字化けをしていますが開きます。フォントが悪いのか、ここのペイン(パッド)の文字解析部分が悪いのかわからないのですが、一応使えます。あらかじめ、XamarinでF#を使う方法 | Moonmile Solutions Blog で示したようなアドインを入れておく必要があります。

image

この Gallary の中に「C# interactive」というのがあって、名前の通り C# のインタープリタなようです。試してみようと思って、インストールして動かしてみるのですが、以下なエラーを吐いて落ちてしまいます。

image

んー、元のソースはないかと思って調べると、praeclarum/CSharpInteractive にあります。SQLite.net の作者の方ですね。見ると、mac 上の xamarin studio では動いているようなので、ちょっとソースを覗いてみると、なところでパスが指定されていました。

public class CSharpInteractiveSession : ProcessInteractiveSession
{
public override string GetFileName ()
{
return “/Library/Frameworks/Mono.framework/Versions/Current/bin/csharp”;
}
}

このパスは何なのだろうと思ったら、mono には csharp という C# インタープリタがあるんですね。これをインストールしないダメっぽいのです。んが、Windows の場合は、このパスにインストールされる訳ではないので多分書き換えないと駄目です。

Download – Mono
http://www.go-mono.com/mono-downloads/download.html

から mono 一式をダウンロードすると、csharp.exe は C:/Program Files (x86)/Mono-3.2.3/lib/mono/4.5/csharp.exe なところにあります。この部分を修正して、更に参照設定を monotouch のものから Windows のものに切り替えます。

image

アドインのパッケージのつくり方が分からないので、アドインの DLL を直接変更します。

C:/Users/masuda/AppData/Local/XamarinStudio-4.0/LocalInstall/Addins/CSharpInteractive.CSharpInteractive.1.0/CSharpInteractive.dll

を差し替えてやればOKです。

■これで動くかな?

と思ったのですが、残念。Console アクセスでエラーになっているので、mac のターミナルと windows のコマンドラインの差をうまく変更しないと駄目そうですね。

image

ちなみに、csharp.exe をコマンドラインで動かすとうまく動きます。

image

書いた後に気づいたのですが、Download LINQPad でもいいし、CsharpRepl – Mono でも十分かも。

カテゴリー: C#, Xamarin | Xamarinで C# interactive を動かそう…としたが無理でした はコメントを受け付けていません

内蔵 WebBrowser を Fiddler でトラップする方法

艦これのバトルJSONを再解析(祥鳳改小破編) | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/5517

の続きで、ブラウザの通信をトラップするのに InternetSetOption を使っていたのですが、URLMonInterop.SetProxyInProcess を使ってもできるよ、という話があったので試しに。InternetSetOption 関数自体は結構古くからある方法で定番のようです。たぶん、内部的にも同じことをやっているのかなと。

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    FiddlerApplication.Startup(PROXY_PORT, false, true);
    // SetIESettings("localhost:" + PROXY_PORT);
    URLMonInterop.SetProxyInProcess("127.0.0.1:" + PROXY_PORT.ToString(), "");
    FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
    this.wb.Navigate(URL_LOGIN);
}

こんな感じで1行で済みます。ちなみに InternetSetOption 関数を使った場合はこんな感じ。

internal struct INTERNET_PROXY_INFO
{
    public int dwAccessType;
    public IntPtr proxy;
    public IntPtr proxyBypass;
}
[DllImport("wininet.dll", SetLastError = true)]
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int lpdwBufferLength);

private void SetIESettings(string proxyUri)
{
    const int INTERNET_OPTION_PROXY = 38;
    const int INTERNET_OPEN_TYPE_PROXY = 3;

    INTERNET_PROXY_INFO proxyInfo;
    proxyInfo.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
    proxyInfo.proxy = Marshal.StringToHGlobalAnsi(proxyUri);
    proxyInfo.proxyBypass = Marshal.StringToHGlobalAnsi("local");

    var proxyInfoSize = Marshal.SizeOf(proxyInfo);
    var proxyInfoPtr = Marshal.AllocCoTaskMem(proxyInfoSize);
    Marshal.StructureToPtr(proxyInfo, proxyInfoPtr, true);
    InternetSetOption(IntPtr.Zero, INTERNET_OPTION_PROXY, proxyInfoPtr, proxyInfoSize);
}

サンプルはこんな感じ

https://github.com/moonmile/KcAgent/tree/master/KcAgentBrowser

F12キーを押すとデバッグ用のウィンドウを開きます。そのうち、JSON 解析と swf/mp3 のダウンロード機能とかつける予定。

カテゴリー: 開発, 艦これ | 内蔵 WebBrowser を Fiddler でトラップする方法 はコメントを受け付けていません

XamarinでF#を使う方法

Xamarin Studio は F# をサポートしています…という記述があります。で、具体的にどうするのか?という記述を見かけなかったので、メモとして。

Xamarin Studio の「ツール」→「アドインマネージャ」で Gallary を開きます。

image

  • Mobile Development の F# support for Xamarin.Android development
  • Language bindings の F# Language Binding

の両方をインストールします。たぶん、Mobile のほうが Android に組み込む FSharep.Core で、Language のほうはコンパイラのほうだと思います。見ると、Lua とか D 言語とか並んでいるので、これでもプログラムが組めるのかも。

そうすると「新しいソリューション」でF#のAndroidアプリが組めるようになります。

image

テンプレートのコードも F# なので、Android も F# で組めますね。めでたしめでたし。

image

…と言いたいところなのですが、Xamarin の F# プロジェクトには Potral Class Library がありません。更に言うと、Xamarin が提供する FSharp.Core は Android 用のものはあるのですが、iOS 用はありません。Android 用は C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/MonoAndroid/v1.0/FSharp.Core.dll という DLL を参照していますが、iOS 版はないのです。

追記 2014/03/18
…と思ったのですが、実はあります。 monotouch のフォルダに FSharp.core がありました。なので、これをうまく使うと共有できますね。

ということは、F# で作ると、Android と Windows ストアアプリでは共有できるけど、iOS では共有できない。という結論になるのですが、ちょっと工夫すると F# のコードを Android/iOS/Windows で共有できます。

■Visual Studio で F# の PCL を作る

まずは Visual Studio で「ポータブルクラスライブラリ」を作ります。

image

F# で公開するクラスを使って C# で作った Android/iOS プロジェクトで参照すればよいのです。ビジネスロジックを F# で作りたい場合はこれでOKです。UI 部分も F# で作りたい場合は Xamarin Studio を使えばいいのですが、それだと iOS アプリがハブられてしまうという訳で。

ただし、ここで作った F# のコードですが、これもちょっとコツが要ります。

namespace XamarinFsLib

type OreOre() =
    let (+++) x y =
        x @ y |> Seq.distinct |> Seq.toList
    let (---) x y =
        Set.intersect (Set.ofList x) (Set.ofList y)
        |> Set.toList
    member this.X = "F#"
//    member this.join (x, y) = x +++ y
//    member this.intersect (x, y) = x --- y
    // for C#
    member this.join (x:int[]) (y:int[]) =
        let x' = List.ofArray x
        let y' = List.ofArray y
        x' +++ y' |> List.toArray
    member this.intersect (x:int[]) (y:int[]) =
        let x' = List.ofArray x
        let y' = List.ofArray y
        x' --- y' |> List.toArray

UI用のプロジェクトで FSharp.Core を参照させてしまうと、iOS で動かなくなってしまうので、これの参照しないようにします。また、Visual Studio の PCL では、

C:/Program Files (x86)/MSBuild/../Reference Assemblies/Microsoft/FSharp/.NETCore/3.3.1.0/FSharp.Core.dll を参照しているのですが、Android のほうは

C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/MonoAndroid/v1.0/FSharp.Core.dll を参照するので、不整合が起こります。これもあって、UI 側で FSharp.Core を参照しないようにします。

先の join メソッドで List.toArray しているのは、C# 側で int[] で受け取れるからです。List を使うと F# の List が使われてしまうのでわざと int[] を使っています。こんな風にすると、UI で FSharp.Core を参照しなくて済みます。多分、Generic 関係で渡しても OK だと思います。

あと、C# の場合 join メソッドを多重化できますが、F# ではそのままではできません。なので、引数を Tuple にすればいいのですが…まあ、そうすると F# 側で使うのが面倒なんですけどね。

image

そんなわけで、F# の PCL を Android/iOS アプリが作れるようになりました。

サンプルは 以下からダウンロードできます。
http://1drv.ms/1g1WE9M

ちなみに、このソリューションを Xamarin Studio を開くと以下のようなエラーがでます。mono版の FSharp.Core を期待しているところに、MS版の FSharp.Core を入れられた訳で、仕方がないといえば仕方がないですね。

image

カテゴリー: F#, Xamarin | XamarinでF#を使う方法 はコメントを受け付けていません

オレオレF#でフォークしました

オープン版が https://github.com/fsharp/fsharp にあると分かったので、https://github.com/moonmile/fsharp にフォークを作りました。

ひとまず、数学の記号だけを入れようと思って、[‘u2190’-‘u245f’] な風に範囲しています。文字コード表の「数学記号」なところが入ってます。

image

最近、ちょうど「最短距離の本」を読んでいるところで、その中に集合の記号がでてきます。

image

こんな感じで書けると、数式からF#へ直しやすいかなと。ただし、このままだと、F# Interactive でエラーになるし、Visual Studio の構文チェックが動きません。なので非常に書きづらい…というか、インテリセンスがないと私にはF#が書けない。

まあ、とりあえず、オレオレF# をビルドすると、

open System

let A = [1;2;3]
let B = [3;4;5]

// ∪記号
let (∪) x y =
    x @ y |> Seq.distinct |> Seq.toList
// ∩記号
let (∩) x y =
    Set.intersect (Set.ofList x) (Set.ofList y)
    |> Set.toList

printfn "和集合: %A" (A ∪ B)
printfn "積集合: %A" (A ∩ B)

なコードをビルドできます。実行結果はこちら。

image

カテゴリー: F# | 1件のコメント