ANEtty Document

実践1 : HelloWorld と 足し算

Index

はじめに

この単元では、ネイティブ側から「HelloWorld」と文字列を返してもらうだけの簡単な例と、2つの数字をネイティブに送り、ネイティブ側で足し算を行った上でASに返してもらう例の二つを実装したANEを作成します。

この単元は、以下のプラットフォームが対象です。

  • Windows
  • Mac
  • Android
  • iOS

Step1 : ANEttyで前準備

このステップは全プラットフォーム共通です。

  1. ANEttyを起動し、 上部メニューの「Project」より「New Project」を選択すると、下記の図1のウィンドウが出てきます。それぞれ次のように入力してください。

    • 1ページ目

      • ProjectName : HelloANEWorld
      • ExtensionID : jp.test.ane.HelloANEWorld
      • VersionNumber : 1.0.0
    • 2ページ目

      • Platforms : ターゲットとするプラットフォーム(複数可)
    図1. 新規プロジェクト生成ウィザード
  2. プロジェクトが生成されたら、右部タブの「TempleteSetting」を選択し、メソッドの定義を行います。「Add New Function」で以下のように定義してください。

    • 1つ目

      • FunctionName : getHelloWorld
      • ReturnClassType : String
      • ReturnClassType from Native : 何もしない(same the AS return classにチェック)
      • Arguments : 何も指定しない
    • 2つ目

      • FunctionName : sum
      • ReturnClassType : Number
      • ReturnClassType from Native : 何もしない(same the AS return classにチェック)
      • Arguments : 2つ追加し、それぞれ「ArgumentName : num1, ClassType : Number」「ArgumentName : num2, ClassType : Number」
    図2. 新規プロジェクト生成ウィザード

    図2のように設定したら、そのタブの下部にある「Show Templete」ボタンを押します。すると、それぞれのプラットフォームに適応したテンプレートが出力されます。次のステップ以降はこれを使い、実装を行います。

Step2 : ANE-SWCの生成

このステップは全プラットフォーム共通です。

  • FlashBuilderを起動し、Flexライブラリプロジェクトを作成します。

    • プロジェクト名 : HelloANEWorld_ANE
    • Flex SDKのバージョン : AIR3.0以上がマージされているFlexSDKを選択してください。また、その下にある「Adobe AIR ライブラリを含める」に必ずチェックを入れてください。

    終わったら「次へ」ボタンを押してください。次のダイアログで終了を押して準備完了です。

  • クラスを作成します。HelloANEWorld_ANEプロジェクトのsrcフォルダを選択し、右クリックメニューを開いて、「新規」→「ActionScript クラス」を選択します。出てきたダイアログに、以下の情報を入力してください。なお、この情報はANEttyで出力したテンプレートに沿っています。

    • パッケージ : jp.test.ane
    • 名前 : HelloANEWorld

    入力したら「終了」ボタンを押します。

  • ANEttyで出力したテンプレートの「Flash(ANE-SWC)」タブ内にある「as(Singleton)」を選択して中のテキストをコピーし、先ほど作ったクラスのテキストにペーストして全部上書きします。(パッケージ名とクラス名が本当に合っているかを確認してください。)

  • 上部メニューの「プロジェクト」から、「クリーン」ボタンを選択すると、binフォルダ内にswcができます。これで完了です。

Step3 : ネイティブライブラリの生成

このセクションは、各ターゲット別の実装となります。また、各ネイティブ実装のIDEはバージョンによって表示が異なる場合があります。ご了承ください。

Windows

  1. Visual Studio Express 2012 for Windows Desktopで、上部メニューより「ファイル」→「新しいプロジェクト」を選び、左のリストより「Visual C++」→「Win32」の「Win32 プロジェクト」を選択します。入力項目は、名前を「HelloANEWorld」としてください。他の項目は自動的に編集されます。入力したらOKを押します。確認ダイアログが出ますので、左の「アプリケーションの設定」をクリックし(項目がわかりづらいので注意)、「アプリケーションの種類」でDLLを選択し、完了ボタンを押してください。

    図3. Visual Studio Express 2012 for Windows Desktopでの初期設定
  2. ANEとして通信するためのライブラリを読み込みます。右にあるソリューションエクスプローラーのルートの「HelloANEWorld」を右クリックして、「追加」→「既存の項目」を選択してください。ファイル選択ダイアログが表示されたら、AIR SDKの「lib/win/FlashRuntimeExtensions.lib」を選択し、追加ボタンを押します。

  3. 次に、上と同じように「HelloANEWorld」を右クリックして、「プロパティ」を選び、「構成プロパティ」→「C/C++」→「全般」→「追加のインクルードディレクトリ」で、AIR SDKの「include」フォルダを追加します。或いは、プロジェクトフォルダへ「FlashRuntimeExtensions.h」を直接コピーしてください。

    図4. Visual Studio Express 2012 for Windows Desktopでの「追加のインクルードディレクトリ」指定
  4. ソリューションエクスプローラーから「stdafx.h」を選択し、開きます。開いたら次に、ANEttyで出力されたWindows用テンプレート「Visual C++(Win)」タブの「stdafx.h」を選択し、そこに記述してあるテキストを、stdafx.hの一番最後に追加します。

  5. 同じく、ソリューションエクスプローラーから「dllmain.cpp」を開き、ANEttyで出力されたWindows用テンプレート「Visual C++(Win)」タブの「dllmain.cpp」を選択してその内容をdllmain.cppの一番最後に追加します。

  6. dllmain.cppの以下の部分を記述します。

    • JpTestAneHelloANEWorldgetHelloWorldメソッドの「const char* returnString = "";」の部分を以下のように記述します。

      const char* returnString = "Hello ANE World from Windows native.";

    • JpTestAneHelloANEWorldsumメソッドの「double returnDouble = 0.0;」の部分を以下のように記述します。

      double returnDouble = arg0_Number + arg1_Number;

  7. これでネイティブの組み込みは終了です。dllファイルを書き出します。上部メニューの「ビルド」から、念のため一回「ソリューションのクリーン」を行い、その後「ソリューションのビルド」を行います。ビルド中のメッセージの一番最後に「========== ビルド: 1 正常終了、0 失敗、0 更新不要、0 スキップ ==========」と出れば終了です。

Mac

  1. Xcodeを開き、プロジェクトを作成します。初期画面の「Create a new Xcode project」を選択するか、上部メニューより「File」→「New」→「Project...」を選択してください。ウィザードには以下のように入力してください。

    • 1ページ目

      • 「OS X」→「Framework & Library」→「Cocoa Framework」を選択する
    • 2ページ目

      • Project Name : HelloANEWorld
      • Company Identifier : jp.test.ane
    • 3ページ目は、プロジェクトを保存するところを選択します。選択後、「Create」ボタンを押して終了してください。

  2. 次に、プロジェクトの設定をします。プロジェクトツリーのルートアイコンを選択すると設定画面が出ますので、 いくつか設定を行います。

    • Build Settings -> Architectures -> Architectures : 32-bit Intel
    • Build Settings -> Build Options -> Compiler for C/C++/Objective-C : LLVM GCC 4.2
    図5. Mac用ANEを作るための設定
  3. 次に、必要なファイルをインポートします。プロジェクトの「Supporting Files」のフォルダアイコンを選択し、右クリックします。出てきたメニューの「Add Files to "HelloANEWorld"...」を選択すると、ファイル選択画面が出てきます。ここで、AIR SDKの「runtimes/air/mac/Adobe AIR.framework」を選択し、「Add」ボタンを押して、ダイアログを閉じます。

  4. これで準備完了です。制作に移ります。まずXcodeの「ANEHelloWorld.h」の「#import <Foundation/Foundation.h>」の下に「#import <Adobe AIR/Adobe AIR.h>」と入力します。

    次に、ANEttyの出力したテンプレートの「Xcode(Mac, iOS)」タブから「c_h」を選択し、テキストを全部コピーします。そのテキストをXcodeの「ANEHelloWorld.h」内の「@interfaceの行」と「@endの行」の間にペーストします。

  5. 次に、ANEttyの出力したテンプレートの「Xcode(Mac, iOS)」タブから「c_m」を選択し、テキストを全部コピーします。そのテキストをXcodeの「ANEHelloWorld.m」内の「@implementationの行」と「@endの行」の間にペーストします。

  6. 「ANEHelloWorld.m」の以下の部分を記述します。

    • JpTestAneHelloANEWorldgetHelloWorldメソッドの「const char* returnString = "";」の部分を以下のように記述します。

      const char* returnString = "Hello ANE World from MacOS native.";

    • JpTestAneHelloANEWorldsumメソッドの「double returnDouble = 0.0;」の部分を以下のように記述します。

      double returnDouble = arg0_Number + arg1_Number;

  7. 最後にビルドを行います。上部メニューの「Product」から一度「Clean」を選び、終わったら「Build」を選択しましょう。画面に「Build Succeeded」と出たら完了です。(警告が出ているかもしれませんが、恐らく問題ありません)

Android

  1. eclipseを開き、メニューから「ファイル」→「新規」→「その他」を選び、プロジェクト選択ダイアログが出たら、「Android」から「Androidアプリケーション・プロジェクト」を選択する。

  2. 新規Androidアプリケーションで以下のように入力します。

    • アプリケーション名 : HelloANEWorld
    • プロジェクト名 : HelloANEWorld
    • パッケージ名 : jp.test.ane.helloaneworld
    • その他は適宜に入れてください。ただし、最小必須SDKはAPI8以上です。(AIR for Androidが2.2以上対応のため)
    図6. Androidプロジェクト作成ウィザード
  3. 「アクティビティーの作成」のチェックを外します。

  4. ランチャーアイコンの構成は特に必要ないので、そのまま「完了」ボタンをクリックします。

  5. HelloANEWorldのプロジェクトが出来ますので、それを開き、まずはANEを扱うための外部ライブラリをインポートします。プロジェクトのプロパティを開き、「Java のビルド・パス」から「ライブラリー」を開き、そこにある「外部 Jar 追加…」ボタンを押します。すると選択画面が開いていますので、バージョン3.0以上のAIR SDKから「lib/android/FlashRuntimeExtensions.jar」を選択してください。選択が終わったらOKを押してプロパティ編集を終了します。

  6. ここからクラス作成に入ります。プロジェクトのsrcフォルダを選択し、右クリックでコンテキストメニューを出してください。その中から「新規」→「クラス」を選択してください。ダイアログが出ますので、以下のように入力します。

    • ソース・フォルダー : (そのまま)
    • パッケージ : jp.test.ane.helloaneworld(ANEttyで出力したテンプレートの最上部にあります)
    • 名前 : HelloANEWorldExtension
    • スーパークラス : (そのまま)
    • インターフェイス : com.adobe.fre.FREExtension(右の追加ボタンからでるダイアログで選択します)

    完了ボタンを押すと、クラスが作成されて表示されますので、ANEttyで出力されたテンプレートダイアログの「eclipse(Android)」より「java_ext_templete」で出力されたクラスを丸ごとコピペしてください。(パッケージ名とクラス名が本当に合っているかを確認してください。)

  7. そうすると、createContextメソッド内において、HelloANEWorldContextの記述部分にエラーが出ているはずです。ここから、クイックフィックス機能を使い、HelloANEWorldContextクラスを作成します。

    エラーが出ている部分で右クリックし、コンテキストメニューより「クイック・フィックス」を選択します。すると、いくつか選択肢が出て、その中に「クラス 'HelloANEWorldContext' を作成します」という項目があるので選択すると、新しいクラスを作成するダイアログが出ます。これは項目が全ていい感じで埋まっていますので、このまま完了を押してしまいます。

  8. HelloANEWorldContextクラスが作成されますので、先ほどと同じように、ANEttyのテンプレートダイアログの「eclipse(Android)」より「java_ctx_templete」で出力されたクラスを丸ごとコピペしてください。(パッケージ名とクラス名が本当に合っているかを確認してください。)

    すると、先ほどと同じような感じで、「GetHelloWorldFunction」と「SumFunction」にエラーが出ていますので、クイックフィックスでクラスを作成します。これも、ダイアログの内容はそのままに完了ボタンを押してください。

  9. GetHelloWorldFunctionクラスとSumFunctionクラスが作成されますので、先ほどと同じように、ANEttyのテンプレートダイアログの「eclipse(Android)」よりそれぞれ「getHelloWorld」「sum」と出力されたクラスを丸ごとコピペしてください。(パッケージ名とクラス名が本当に合っているかを確認してください。)

    それぞれのクラスに、以下の記述を行います。

    • GetHelloWorldFunctionクラスは、「String returnString = "";」の部分を以下のようにします。

      String returnString = "Hello ANE World from Android native.";
    • SumFunctionクラスは、「double returnNumber = 0;」の部分を以下のようにします。

      double returnNumber = arg0_Number + arg1_Number;
  10. これでネイティブの組み込みは終了です。jarファイルを書き出します。プロジェクトを右クリックし、「エクスポート」→「Java」→「JAR ファイル」を選択してください。出てくるダイアログでJARファイルのエクスポート先を指定して完了を押します。名前はなんでも構いませんが、プロジェクト名と同じ「HelloANEWorld」にしておくと、迷わなくて済むかと思います。

iOS(iPhone-ARM, iPhone-x86)

  1. Xcodeを開き、プロジェクトを作成します。初期画面の「Create a new Xcode project」を選択するか、上部メニューより「File」→「New」→「Project...」を選択してください。ウィザードには以下のように入力してください。

    • 1ページ目

      • 「iOS」→「Framework & Library」→「Cocoa Touch Static Library」を選択する。
    • 2ページ目

      • Project Name : HelloANEWorld
      • Company Identifier : jp.test.ane

    3ページ目は、プロジェクトを保存するところを選択します。選択後、「Create」ボタンを押して終了してください。

  2. 次に、必要なファイルをインポートします。プロジェクトの「Supporting Files」のフォルダアイコンを選択し、右クリックします。出てきたメニューの「Add Files to "HelloANEWorld"...」を選択すると、ファイル選択画面が出てきます。ここで、AIR SDKの「include/FlashRuntimeExtensions.h」を選択し、「Add」ボタンを押して、ダイアログを閉じます。

  3. Xcodeの左上部にデバイスを選択するところがあります。もしiPhone実機用のANE(iPhone-ARM)を扱う場合は、「iOS Device」を選択してください。iOSシミュレータ用のANE(iPhone-x86)を扱う場合は、適切なiOSシミュレータを選択してください。

    図7. ターゲット(iPhone-ARM or iPhone-x86)の変更
  4. これで準備完了です。制作に移ります。まずXcodeの「ANEHelloWorld.h」の「#import <Foundation/Foundation.h>」の下に「#import "FlashRuntimeExtensions.h"」と入力します。

    次に、ANEttyの出力したテンプレートの「Xcode(Mac, iOS)」タブから「c_h」を選択し、テキストを全部コピーします。そのテキストをXcodeの「ANEHelloWorld.h」内の「@interfaceの行」と「@endの行」の間にペーストします。

  5. 次に、ANEttyの出力したテンプレートの「Xcode(Mac, iOS)」タブから「c_m」を選択し、テキストを全部コピーします。そのテキストをXcodeの「ANEHelloWorld.m」内の「@implementationの行」と「@endの行」の間にペーストします。

  6. 「ANEHelloWorld.m」の以下の部分を記述します。

    • JpTestAneHelloANEWorldgetHelloWorldメソッドの「const char* returnString = "";」の部分を以下のように記述します。

      const char* returnString = "Hello ANE World from iOS native.";

    • JpTestAneHelloANEWorldsumメソッドの「double returnDouble = 0.0;」の部分を以下のように記述します。

      double returnDouble = arg0_Number + arg1_Number;

  7. 最後にビルドを行います。上部メニューの「Product」から一度「Clean」を選び、終わったら「Build」を選択しましょう。画面に「Build Succeeded」と出たら完了です。なお、iOSの場合とiOSシミュレータの場合で、.aファイルの保存場所が違いますので、間違わないようにご注意ください。

注意:Windowsにおいて、パッケージングをしようとすると「'java' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。」と出ることがあります。その場合は、FAQの「WindowsでANEを作ろうとすると、「'java' は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。」と出てコンパイルできない。」を参照してください。

Step4 : aneファイルの生成

このステップは全プラットフォームほぼ共通です。

  1. ANEttyに戻り、先ほど作成したANE-SWCとネイティブライブラリをセットします。まずはANE-SWCをセットします。Step2で作成したswcファイルをANEttyの「ExtInfo(General)」タブにある「ANE-Interface-SWC」にドラッグ&ドロップするか、「...」ボタンを押してファイル選択ダイアログを開き、該当ファイルを選択してください。

  2. 次にネイティブライブラリをセットします。例えばWindowsであれば、「Platforms」タブ内の「Windows-x86」タブ内にある「NativeLibraryPath」のところにドラッグ&ドロップするか、「...」ボタンを押してファイル選択ダイアログを開き、該当ファイルを選択してください。他のプラットフォームも同様です。

  3. 最後に「ExtInfo(General)」タブの「ANE Export Path」をセットします。これはaneファイルの保存先です。既存の場所に置くのであれば、そのaneファイルをドラッグ&ドロップするか、「...」ボタンを押してファイル選択ダイアログを開き、保存先とファイル名を決定してください。

  4. ANE Versionは自動的に最低限のバージョンに設定されますが、必要であればバージョンを変更してください。

  5. その他、オプションで何か必要な個所があれば設定してください。

    • Copyright(著作権)
    • Title(タイトル)
    • Description(説明)
    • AIR SDK(デフォルトではなくプロジェクト別のAIR SDKを使用する場合に設定)
    • Certification系(証明書)
  6. Compileボタンを押してしばらく待ちます。「ANE build is completed!」と出れば完了です。指定した場所にaneファイルがあることを確認してください。

Step5 : AIRアプリの作成と実行

このステップは全プラットフォームほぼ共通です。

  1. FlashBuilderを立ち上げ、Windows、Macで扱うANEの場合は「Flex プロジェクト」、Android、iOSで扱うANEの場合は「Flex モバイルプロジェクト」を新規作成します。

    • 1ページ目

      • プロジェクト名 : HelloANEWorld_APP
      • FlexSDK のバージョン : ANEttyで指定したバージョンより高いAIRSDK(あるいはマージされているFlexSDK)を選択してください。
      • (デスクトップの場合のみ)アプリケーションの種類 : デスクトップ
    • 2ページ目

      • (モバイルの場合のみ)アプリケーションテンプレート : 空白

    あとは適宜入力して、プロジェクトのセットアップを終わらせてください。

  2. 先ほど作ったaneファイルをリンクします。パッケージエクスプローラーにあるプロジェクトを右クリックして、コンテキストメニューより「プロパティ」→「Flex ビルドパス」を選択し、「ネイティブエクステンション」のタブを選択します。「ANE を追加...」というボタンをクリックするとANEファイル選択用のダイアログが開きますので、先ほど作成したaneファイルを選択してください。

    なお、「AIR アプリケーション記述子を更新」のチェックボックスはチェックしたままにしてください。

    選択し終わったら「OK」を押し、選択したファイルがリストに追加されていることと、緑色のチェックが入っていることを確認してください。

  3. 上記を確認したら、次は追加したANEをAIRでパッケージングするために、パッケージ化の設定を行います。同じプロパティのウィンドウの左リストから「Flex ビルドのパッケージ化」を選択し、その中の「ネイティブエクステンション」のタブを開いてください。

    すると、先ほど設定したaneファイルがリストに入っています。リストの一番右端に「パッケージ」という項目があり、チェックボックスがありますので、それにチェックを入れてください。その際に「この ANE はアプリケーションで使用されていますが、アプリケーション記述しないでは参照されていません。エクステンション ID が ANE に追加されます。」とアラートが出ます。「はい」を押して閉じてください。

    問題なくチェックが入ったら、これで終了です。「OK」ボタンを押して、プロパティウィンドウを閉じましょう。

  4. これで準備ができました。次はいよいよ、AIRアプリケーションを作ります。ドキュメントクラスに、以下のように入力します(ルートタグとその属性が違うだけで、ルートより下の構成は全く一緒です)。

    デスクトップ

    <?xml version="1.0" encoding="utf-8"?>
    <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                           xmlns:s="library://ns.adobe.com/flex/spark"
                           xmlns:mx="library://ns.adobe.com/flex/mx"
                           creationComplete="creationCompleteHandler(event)">
        <fx:Script>
            <![CDATA[
                import mx.events.FlexEvent;
    
                import jp.test.ane.HelloANEWorld;
    
                protected function creationCompleteHandler(event:FlexEvent):void
                {
                    trace("getHelloWorld : " + HelloANEWorld.getInstance().getHelloWorld());
                    trace("sum : " + HelloANEWorld.getInstance().sum(1, 2));
                }
    
            ]]>
        </fx:Script>
        <fx:Declarations>
            <!-- 非ビジュアルエレメント (サービス、値オブジェクトなど) をここに配置 -->
        </fx:Declarations>
    </s:WindowedApplication>	

    モバイル

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160"
                   creationComplete="creationCompleteHandler(event)">
        <fx:Script>
            <![CDATA[
                import mx.events.FlexEvent;
    
                import jp.test.ane.HelloANEWorld;
    
                protected function creationCompleteHandler(event:FlexEvent):void
                {
                    trace("getHelloWorld : " + HelloANEWorld.getInstance().getHelloWorld());
                    trace("sum : " + HelloANEWorld.getInstance().sum(1, 2));
                }
    
            ]]>
        </fx:Script>
        <fx:Declarations>
            <!-- 非ビジュアルエレメント (サービス、値オブジェクトなど) をここに配置 -->
        </fx:Declarations>
    </s:Application>	
  5. これで完了です。デバッグしてみましょう。コンソールに以下の文章が出れば無事に完成です!(例はWindowsのANEです)

    getHelloWorld : Hello ANE World from Windows native.
    sum : 3

    注意:Mac用のANEはデバッグでは動かない場合があります(Error #3500: The extension context does not have a method with the name GetHelloWorld)。ADL、及びFlashBuilderのバグと考えてよいかと思いますが、一応解決策があります。解決策は「FAQ - ANEを実行しようとすると「Error #3500: The extension context does not have a method with the name メソッド名」とエラーが出る」の後半をご覧ください。