ANE HandsOn Seminar #1 Hello World! for MacOS

目次

  1. ANE-SWCの作成
  2. ネイティブライブラリの作成
    1. 前準備
    2. ヘッダーファイルの記述
    3. 実装ファイルの記述
  3. aneファイルの作成
  4. AIRアプリケーションの作成
  5. AIRアプリケーションの実行

サンプルファイル

Section 1 : ANE-SWCの作成

  1. FlashBuilder4.6を開き、「ファイル -> 新規 -> Flexライブラリプロジェクト」を作成します。

    • プロジェクト名:Seminar1HelloWorld_ane
    • Flex SDK:4.6.0
    • 「Adobe AIRライブラリを含める」にチェックが入っている事を確認。

    その後は、終了を押して作成完了します。

  2. srcフォルダを右クリックし、「新規 -> ActionScriptクラス」を選択。

    • パッケージ名:jp.ane.sample
    • 名前:NativeHelloWorld

    その後は、終了を押して作成完了します。

  3. 以下のようにクラスを記述します。

    package jp.ane.sample
    {
    	import flash.external.ExtensionContext;
    
    	public class NativeHelloWorld
    	{
    		
    		private var _context:ExtensionContext;
    		
    		public function NativeHelloWorld()
    		{
    			_context = ExtensionContext.createExtensionContext("jp.ane.sample.HelloWorld", null);
    		}
    		
    		public function getHelloWorld(text:String):String
    		{
    			var returnStr:String;
    			
    			try
    			{
    				returnStr = _context.call("GetHelloWorld", text) as String;
    			} 
    			catch(error:Error) 
    			{
    				returnStr = error.message;
    			}
    			
    			return returnStr;
    		}
    	}
    }
    							
  4. プロジェクトフォルダのbinフォルダに「Seminar1HelloWorld_ane.swc」ファイルが出来ていれば、次の項目へ。

  5. プロジェクトフォルダにaneフォルダを新規作成します。

Section 2 : ネイティブライブラリの作成

前準備

  1. Xcode4.2で「Mac OS X -> Framework & Library -> Cocoa Framework」を選択。プロジェクトを生成する。

    • プロジェクト名:Seminar1HelloWorldForMac
  2. プロジェクト内Frameworkフォルダを右クリック、Add Files to〜を選択し、「FlexSDK/runtimes/air/mac/Adobe AIR.framework」をインポート
  3. プロジェクトの設定を開き、「Build Settings -> Architectures -> Architectures」を「32-bit Intel」にする。
  4. Lionの場合は、「Build Settings -> Build Options -> Compiler for C/C++/Objective-C」を「LLVM GCC 4.2」に設定する。

ヘッダーファイルの記述

  1. 「#import <Adobe AIR/Adobe AIR.h>」を@interfaceの上に書く。

  2. 以下のコードをヘッダファイルの@interfaceと@endの間にコピペする(ExtensionInitializerの記述)

    void jpAneSampleHelloWorldExtInitializer(
                                                     void** extDataToSet,
                                                     FREContextInitializer* ctxInitializerToSet,
                                                     FREContextFinalizer* ctxFinalizerToSet
                                                     );
    									
  3. 以下のコードをヘッダファイルのExtensionInitializerの下にコピペする(ExtensionFinalizerの記述)

    void jpAneSampleHelloWorldExtFinalizer(void* extData);
    									
  4. 以下のコードをヘッダファイルのExtensionFinalizerの下にコピペする(ContextInitializerの記述)

    void jpAneSampleHelloWorldContextInitializer(void* extData, 
                                                 const uint8_t* ctxType, 
                                                 FREContext ctx,
                                                 uint32_t* numFunctionsToTest, 
                                                 const FRENamedFunction** functionsToSet);
    									
  5. 以下のコードをヘッダファイルのContextInitializerの下にコピペする(ContextFinalizerの記述)

    void jpAneSampleHelloWorldContextFinalizer(FREContext ctx);
    									
  6. 以下のコードをヘッダファイルのContextFinalizerの下にコピペする(呼び出し用メソッドの記述)

    FREObject GetHelloWorld(
                        FREContext ctx,
                        void* funcData,
                        uint32_t argc,
                        FREObject arg[]
                        );
    									

実装ファイルの記述

  1. 以下のコードを、実装ファイルの@endの上にコピペする。(ExtensionInitializerの実装)

    void jpAneSampleHelloWorldExtInitializer(void** extDataToSet, 
                                             FREContextInitializer* ctxInitializerToSet,
                                             FREContextFinalizer* ctxFinalizerToSet)
    {
        *extDataToSet = NULL;
        *ctxInitializerToSet = &jpAneSampleHelloWorldContextInitializer;
        *ctxFinalizerToSet = &jpAneSampleHelloWorldContextFinalizer;
    }
    									
  2. 以下のコードを、実装ファイルのExtensionInitializerの下にコピペする。(ExtensionFinalizerの実装)

    void jpAneSampleHelloWorldExtFinalizer(void* extData)
    {
        return;
    }
    									
  3. 以下のコードを、実装ファイルのExtensionFinalizerの下にコピペする。(ContextInitializerの実装)

    void jpAneSampleHelloWorldContextInitializer(void* extData, 
                                                 const uint8_t* ctxType, 
                                                 FREContext ctx,
                                                 uint32_t* numFunctionsToTest, 
                                                 const FRENamedFunction** functionsToSet) 
    {
        *numFunctionsToTest = 1;
        FRENamedFunction* func = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*1);
        func[0].name = (const uint8_t*)"GetHelloWorld";
        func[0].functionData = NULL;
        func[0].function = &GetHelloWorld;
        
        *functionsToSet = func;
    }
    									
  4. 以下のコードを、実装ファイルのContextInitializerの下にコピペする。(ContextFinalizerの実装)

    void jpAneSampleHelloWorldContextFinalizer(FREContext ctx)
    {
        return;
    }
    									
  5. 以下のコードを、実装ファイルのContextInitializerの下にコピペする。(呼び出し用メソッドの実装)

    FREObject GetHelloWorld(
                            FREContext ctx,
                            void* funcData,
                            uint32_t argc,
                            FREObject argv[])
    {
        FREObject returnObj;
        uint32_t userTextLength;
        const uint8_t* userText;
        const char* returnStr;
        
        userTextLength =  strlen((const char*)argv[0])+1;
        FREGetObjectAsUTF8(argv[0], &userTextLength, &userText);
        
        NSString *userTextStr = [NSString stringWithUTF8String:(const char*)userText];
        NSString *appendTextStr = [NSString stringWithFormat:@"(from iOS Extension)"];
          
        returnStr = [[NSString stringWithFormat:@"%@%@", userTextStr, appendTextStr] UTF8String];
        
        FRENewObjectFromUTF8(strlen(returnStr)+1 , (const uint8_t*)returnStr, &returnObj);
        
        return returnObj;
    }
    									
  6. Xcodeのメニュー、Product -> Cleanをして、Product -> Buildをする。Build Succeededと出たら、これでネイティブの実装は完了。

Section 3 : aneファイルの作成

  1. ANEttyを立ち上げ、以下の内容を記述する。

    設定項目名 入力
    ExtensionID jp.ane.sample.HelloWorld
    VersionNumber 1.0.0
    ANE Version 3.1
    SWC Path Seminar1HelloWorld_ane.swcをD&DかFinderで選択
    Export Path 先ほどのSeminar1HelloWorld_aneプロジェクトフォルダのaneフォルダを選択し、ファイル名にNativeHelloWorld.aneと入力する。
    Platform MacOS-x86にチェックを入れる。
    • NativeLibraryPath : 先ほど作った.frameworkフォルダをD&Dかダイアログで選択する。

      Xcode内のlibSeminar1HelloWorldForMac.frameworkを右クリックで「Show in Finder」をクリックすると、Finderで表示される。

      もし赤文字になっている場合は、以下の場所から頑張ってみつける。

      /Users/(UserName)/Library/Developer/Xcode/DerivedData/(ProjectName)/Build/Products/Debug/

    • Initializer : jpAneSampleHelloWorldExtInitializer
    • Finalizer : jpAneSampleHelloWorldExtFinalizer
    ADT Path(AIR Development Tool) adtファイル( /Applications/Adobe Flash Builder 4.6/sdks/4.6.0/bin )をD&DかFinderで選択
    CertificationFile Path P12証明書をD&DかFinderで選択。( Appleのではなく、ADTで作成された証明書 )
  2. Compileボタンを押してしばらくし、「Success」が出ればaneファイルの完成。Seminar1HelloWorld_aneプロジェクトのaneフォルダにNativeHelloWorld.aneがあるのを確認する。

Section 4 : AIRアプリケーションの作成

  1. FlashBuilder4.6で「新規 -> Flex プロジェクト」を選択

    • プロジェクト名 : Seminar1HelloWorld_DesktopApp
    • アプリケーションの種類:デスクトップ(Adobe AIR で実行)
    • ビルドパスのところで、「ネイティブエクステンション」タブをクリック。「フォルダーを追加」ボタンを押し、参照で、aneフォルダを指定。OKを押すとチェックが始まる。
    • 終了で完了。
  2. srcフォルダ内のSeminar1HelloWorld_DesktopApp.mxmlに以下を記述する。

    <?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="creationCompleted(event)">
    	
    	<fx:Script>
    		<![CDATA[
    			import jp.ane.sample.NativeHelloWorld;
    			
    			import mx.events.FlexEvent;
    			
    			private var _nativeHelloWorld:NativeHelloWorld;
    			
    			[Bindable]
    			private var _resultStr:String;
    			
    			protected function creationCompleted(event:FlexEvent):void
    			{
    				_nativeHelloWorld = new NativeHelloWorld();
    				_resultStr = "ここに結果が表示されます。";
    			}
    			
    			protected function sendTextToNative(event:MouseEvent):void
    			{
    				try
    				{
    					_resultStr = _nativeHelloWorld.getHelloWorld(inputArea.text);
    				} 
    				catch(error:Error) 
    				{
    					_resultStr = error.message;
    				}
    			}
    			
    		]]>
    	</fx:Script>
    	<fx:Declarations>
    		<!-- 非ビジュアルエレメント (サービス、値オブジェクトなど) をここに配置 -->
    	</fx:Declarations>
    	
    	<s:layout>
    		<s:VerticalLayout gap="20" />
    	</s:layout>
    	
    	<s:TextArea id="inputArea" text="今日はセミナーにお越し頂きありがとうございます。" width="100%" height="50"/>
    	<s:TextArea text="{_resultStr}" width="100%" />
    	<s:Button width="100%" height="50" label="HelloWorld!" click="sendTextToNative(event)" />
    </s:WindowedApplication>
    							

Section 5 : アプリケーションの実行

  1. 上部のアイコンメニューより「実行」を押す。(但し、エラーが出る。)

    FlashBuilder4.6での実行では、MacでANEを使おうとすると#3500のエラーが起こる。一度リリースビルドを作成してインストールして実行するか、面倒な事をしてADLをコマンドラインで立ち上げるかの2択。

    ArgumentError: Error #3500: The extension context does not have a method with the name (メソッド名).
    						
    This is a known, reported bug with Flash Builder 4.6 for Mac. It doesn’t call adl (the debugger version of AIR) with the proper parameters to include the .ANE. You can either export a release version (in which case, it will work), or you can launch ADL from the command line (or ANT, which is what I ended up doing). It is a real pain, and threw me for at least two weeks while I was trying to build the MAC version. I have a blog post coming up (I still need to put together all of my notes) on exactly how to get around it until Adobe fixes the issue. http://quetwo.com/2011/12/01/arduinoconnector-ane/#comment-1103

    上の記事で「後で記事書くよ」という、その記事はこちら。http://quetwo.com/2011/12/03/working-with-air-native-extensions-on-the-mac/

  2. 上部メニューの「プロジェクト -> リリースビルドのエクスポート」を選び、「書き出し形式」に「署名済みネイティブインストーラー」を選択し、「次へ」を押す。電子署名部分を入力し(手順は割愛)、終了を押す。あとはインストールし、実行する。