$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Embeddinator-4000から学ぶXamarinの基礎
Search
Atsushi Eno
August 19, 2017
Technology
1
7.5k
Embeddinator-4000から学ぶXamarinの基礎
https://jxug.connpass.com/event/60770/
Atsushi Eno
August 19, 2017
Tweet
Share
More Decks by Atsushi Eno
See All by Atsushi Eno
Android Audio: Beyond Winning On It
atsushieno
0
5.9k
Can we build better music software ecosystems for more generative era?
atsushieno
0
490
Some Music Libraries for Kotlin (with some .NET -> Kotlin migration stories)
atsushieno
0
680
Building App Extensions equivalents on Android (maybe?)
atsushieno
1
830
Taking trends in music app development into the future mobile ecosystem
atsushieno
0
780
DTM entry level hands-on
atsushieno
0
690
[COSCUP2024] Catching up Trends in Audio App Development
atsushieno
0
880
Building Kotlin Multiplatform Libraries in 2024
atsushieno
1
4.4k
Kotlin Multiplatformで MIDI 1.0/2.0 ライブラリを作っている話
atsushieno
1
860
Other Decks in Technology
See All in Technology
文字列の並び順 / Unicode Collation
tmtms
3
600
re:Invent 2025 ~何をする者であり、どこへいくのか~
tetutetu214
0
220
Challenging Hardware Contests with Zephyr and Lessons Learned
iotengineer22
0
230
非CUDAの悲哀 〜Claude Code と挑んだ image to 3D “Hunyuan3D”を EVO-X2(Ryzen AI Max+395)で動作させるチャレンジ〜
hawkymisc
2
200
生成AIを利用するだけでなく、投資できる組織へ / Becoming an Organization That Invests in GenAI
kaminashi
0
100
AWSを使う上で最低限知っておきたいセキュリティ研修を社内で実施した話 ~みんなでやるセキュリティ~
maimyyym
2
1.7k
S3を正しく理解するための内部構造の読解
nrinetcom
PRO
2
120
ChatGPTで論⽂は読めるのか
spatial_ai_network
10
29k
AWS CLIの新しい認証情報設定方法aws loginコマンドの実態
wkm2
6
750
品質のための共通認識
kakehashi
PRO
3
260
ExpoのインダストリーブースでみたAWSが見せる製造業の未来
hamadakoji
0
140
生成AI活用の型ハンズオン〜顧客課題起点で設計する7つのステップ
yushin_n
0
230
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Typedesign – Prime Four
hannesfritz
42
2.9k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
7.9k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
286
14k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.1k
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.6k
Producing Creativity
orderedlist
PRO
348
40k
Designing Experiences People Love
moore
143
24k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Testing 201, or: Great Expectations
jmmastey
46
7.8k
The Pragmatic Product Professional
lauravandoore
37
7.1k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Transcript
Embeddinator-4000から学ぶ Xamarinの基礎
[email protected]
Introduction
Embeddinator-4000とは?
Xamarinをネイティブで使う? • Native Embedding (Xamarin.Forms) ◦ プラットフォーム固有のコントロールを Xamarin.FormsのLayoutの子として追加 • Forms
Embedding (Xamarin.Forms) ◦ Xamarin.Formsのページをプラットフォーム固有の UIコントロールとして追加 • Embeddinator-4000 ◦ Mono/Xamarinで書いたコードを、プラットフォームネイティブのコードとして利用 Xamarin.Forms Xamarin Native Xamarin Native Xamarin.Forms Native (objc/Java) Xamarin
何が出来るのか • .NET DLLに対応するC/Java/objcバインディングを生成できる • Xamarin.Androidのライブラリ プロジェクトをaarに変換できる ◦ 「Xamarin.Androidのライブラリ プロジェクト」には
Xamarin.FormsのNative Embeddingも含まれる(!) • Mac, iOS (Objective-C)も実装されている ◦ 公式にはまだAndroidのみ ※「aarって何?」という人向けではない
どうやって使うのか? • nugetでembeddinator-4000をインストール • コマンドラインで実行 • mono packages/Embeddinator-4000.0.2.0.80/tools/Embeddinator-4000.exe -platform=Android -gen=Java
-c project/bin/Debug/MyLibrary.dll • mono packages/Embeddinator-4000.0.2.0.80/tools/objcgen.exe -platform=MacOS -gen=Obj-C -c project/bin/Debug/MyLibrary.dll • mono packages/Embeddinator-4000.0.2.0.80/tools/Embeddinator-4000.exe -platform=Linux -gen=c -c project/bin/Debug/MyLibrary.dll
何が出来上がるのか?
どんなライブラリが生成されるのか? (C) using System; public class MyLibrary { public string
Hello (string input) { return "Hello, " + input; } } #include "glib.h" #include "mono_embeddinator.h" #include "c-support.h" typedef MonoEmbedObject MyLibrary; MONO_EMBEDDINATOR_API MyLibrary* MyLibrary_new(); MONO_EMBEDDINATOR_API const char* MyLibrary_Hello(MyLibrary* object, const char* input);
どんなライブラリが生成されるのか? (Java) • Java APIのjarとmonodroidランタイム、アセンブリをassetsに含むaar ◦ resがまだ含まれていない(困る) • hello worldレベルのaarで約10MB
package xamarin_forms_core.xamarin.forms; import com.sun.jna.Pointer; import mono.embeddinator.Runtime; ... public class Page extends VisualElement implements ILayout, IPageController { public Page(Pointer object) { super(object); }
どうやっているのか これを理解するには、Xamarinの動作原理を理解する必要がある 以下の質問にYesと答えられる人にはすぐ概要が分かる • iOSやAndroidのアプリケーション(iOSならXcode + Objective-C、AndroidならAndroid Studio + Java)が、ど
のように作られているのかを理解している • それぞれのプラットフォームで、ネイティブライブラリをビルドして使用できる • monoがembedded APIを用意していることを知っている • Xamarinアプリケーションが各プラットフォームの標準に沿っていると知っている
Xamarin.Android の基礎
embedded mono ネイティブに組み込んで monoを使って.NETコードを 実行できるCライブラリ リフレクションAPIのようなもの [doc] embedding mono scripting
engineなどに便利
monoランタイムによるアプリ起動の流れ main() mscorlibのロード machine.configなどのロード AppDomainの生成 アセンブリのロード CILの実行 この流れは全部mono embedded APIで実装できる
.NETコードのエントリポイントは Main()とは限らない embedded monoなら任意のメソッドから実行可能 .NETにも同様の機能がある( CLR Hosting) ※Silverlight、VSTO $mono hello.exe Hello, C#
iOS/Xamarin.iOS 今回はまだサポートされていないし、時間も足りないので省略… • C/objective-c/swiftのコードはclang+llvmでネイティブにコンパイルされる ◦ 実際に開発者が使うのはXcodeとか、xcodebuildなどのビルドツール • プログラムはmain()から普通に開始 • embedded
monoは `Mono.framework` になっている = リンクするだけ • ObjCRuntime (C API)とembedded monoの間で相互運用 ◦ Xamarin.iOSのAPIは全てこの応用。 strongly typed iOS-ObjCRuntime API
標準的なAndroidアプリはどのように作るか • Android Studioで開発するのが一般的 • JavaまたはKotlinでコーディング • ビルドシステムはGradle • 外部ライブラリはjarまたはaar
◦ jarはコードだけ、aarはネイティブライブラリとかリソースも ◦ パッケージ管理はMaven (主にjcenterサーバー) • ビルドされるアプリケーションはapk ◦ Javaの*.classはdex (dalvik bytecode)に変換 ◦ apkは(zipalignされた)zipアーカイブ
Androidアプリでnative libsを使う ※libmonoはネイティブライブラリ • AndroidはLinuxベースのOS • Android NDKでビルド (tools: gcc
or clang/llvm, libs: bionic libc etc.) • CPUアーキテクチャごとにビルド (armeabi-v7a, aarch64, x86, x86_64, mips) 【CからのJava呼び出し】 ((JNIEnv) env)->CallVoidMethod(klass,...) ※JNIEnvがメタプログラミングの中心 【JavaからのC呼び出し】 boolean native foo(...) ※nativeはJavaのキーワード C#の extern
Xamarin.AndroidとJava/Androidのやり取り ※われわれの Activity.OnCreate() はどう実行されるの か? • XAアプリをビルドすると、Javaから.NETを呼ぶため のJCW (Java callable
wrapper)が生成される ◦ src/md5XXXXXXXXXXXXX/MainActivity.java みたいな感じ ◦ mono embedded APIを間接的に呼び出す libmonodroidの nativeメソッド呼び出し(JNI)として実装されている • AndroidフレームワークがアプリのJCWを呼び出す と関連付けられた.NETコードが実行される
(図解JCW) Android Activity Thread APP JCW Main Activity (.java) onCreate()
C# App Main Activity (.cs) X.A. lib monodroid n_onCreate() "OnCreate()" var method = "GetOnCreate_Landroid_os_Bundle_ Handler"); ... ... mono_runtime_invoke(...); Android側が 呼ぶもの
Androidアプリはどのように実行されるか AndroidフレームワークはJavaで実装されており、 Zygote(Javaもどき)のプロセスで動く。例外は無い • ユーザーがアプリを起動 • AndroidシステムがZygoteプロセスをfork • ActivityThreadクラスがライフサイクルを制御 •
AndroidManifest.xmlを読んで初期化処理 ◦ ContentProviderがあれば実行 (onCreate() など) ◦ Applicationを実行 ◦ main launcher Activityがあれば実行
Xamarin.Androidはどう初期化されるのか? • MonoRuntimeProviderというContentProviderで初期化 ◦ 非公式に一般的な方法 Firebaseなどでも使用 ◦ このタイミングでなくても良い(が初期化以前は使えない) ◦ libmonodroid
▪ embedded monoの初期化 ▪ 全アセンブリのロード ▪ JNI RegisterNatives()でJava/.NETマッピング • JavaアプリケーションループがアプリのJCWを実行 ◦ (JCW = .NETコードをJNI経由で呼び出すJavaクラス) ※Androidの標準的な仕組みに基づいて実現している
Embeddinator-4000
Embeddinator-4000の仕組みの概要 • C(など)のコードからMono/XamarinのマネージドAPIを呼び出す • .NETのアプリに含まれるAPIを「C / Java / Objective-Cから呼び出す」APIを 自動生成してライブラリ化する
• 呼び出されたマネージドコードはmono上で実行される(iOSはAOT-ed) 実は呼び出し層の構成が変わっただけであって、プラットフォーム (objc/Java/C)と.NETの相互運用の仕組みであることに変わりはない Androidが決め打ちのJCWを呼び出す vs. ユーザーが任意のe4k APIを使う
(図解Embeddinator-4000呼び出し) User Java Code e4k Java API Visual Element .java
new xamarin_ forms_core. xamarin.forms. VisualElement() C# App Visual Element (.cs) e4k C API Xamarin. Forms. Core.c "get_Height()" .getHeight() Xamarin_Forms _VisualElement _get_Height()
Cコードの生成 生成ツールは部分的にCppSharpを活用して作られている C++と{好きな言語環境を入れる }の相互運用の自動化は超絶難易度が高いが Cなら簡単(というか、たいてい用意されている) PInvoke、JNI、perl XS、python cypes、node-ffi
Objective-Cコードの生成 • 今回はAndroidの話をするだけでいっぱいいっぱいなので、割愛 • ツールとしてはobjcgen.exe ◦ MonoEmbeddinator4000.exeとは完全に別物の実装 ◦ だいたいTextWriter.WriteLine()で実装している •
MacOSをターゲットにしたら、ライブラリまではビルドできた • iOSはまだ調整が必要そう
Android Javaコードの生成 • 「C/C++の呼び出しを行うJavaコード」を自動生成する • JavaとC++のinteropは現在は一般的にJNIベースの煩雑な手作業 • Embeddinator-4000のコア: e4k C
APIからJNA 呼び出しJavaコードを生成 ◦ JNAのランタイムが実行時にも必要になる(aarに組み込まれる) JNA: Java Native Access (com.sun.jna) Androidをサポートし、事前コード生成を必要としない唯一の選択肢(今回は重要ではない)
考察
Embeddinator-4000の利点 Xamarinアプリケーション開発者にとってのメリット ない それとは関係なく、CppSharpがあるとネイティブ ライブラリの呼び出しが楽になる…かもしれない ※rephrase: C++相互運用は激ムズ ※Xamarinからネイティブライブラリを大量に呼び出していると便利かも
Embeddinator-4000の想定ユーザー(?) • 既存のネイティブアプリでXamarinベースのコードを活用したい人 • 既存のネイティブアプリからXamarinに少しずつコードを移行したい人 • 既存のXamarinアプリからネイティブに土台を移行したい人 • .NET以外の環境でも.NETライブラリの利用を拡大したいライブラリ提供者 ◦
Azure関連のライブラリとか? ◦ ライブラリはMavenに発行することも検討されている
より開かれたXamarin環境 • Embeddinator-4000は「Xamarinでコードを書くとMicrosoft技術に囲い込まれ る」という懸念を晴らすために存在する技術でもある • Xamarinを宣伝したい時に「でもXamarinで全部書くのはこわい…」となった 時に緩和剤のひとつとして機能する側面がある • 「ネイティブで出来るアレやコレができなくなるから…」と言われてXamarinを 利用できなくなっても、埋め込めるチャンスがある
• ただし多用には警戒したほうがよい。相互運用の出入り口が多いとメンテナ ンス地獄になる。ツールの完成度に振り回される • まだ出できたばかりのツールだということを忘れない
まとめ • Xamarinのアプリケーションを埋め込む技術はいろいろあってややこし いので、どれの話をしているか意識して聞いたほうが良い • Xamarinは、iOS/Androidアプリケーションにネイティブコードである libmonoを組み込んで相互運用する技術 • Embeddinatorも、.NET APIを(Xamarinと)mono
embedded API経由で、 相互運用する技術 • レイヤーの重なり方がXamarinアプリケーションと少し違うだけ
宣伝 本セッションの内容は技術書典 3で頒布する Xamarin同人誌(名称未設定)で解説します (2017/10/22 @秋葉原)