(備忘録)ANEを作るテスト

2016年5月21日土曜日

コンピュータ

ANEはAdobe AIR環境でローカルのハードウエアを直接扱える便利な機能です。 これまでは市販のものやフリーで使えるANEを使っていましたが、 自分で作ってみたので備忘録として残しておきます。 ・前提
Flashbuilder4.6 Xcode 7.2.1 Adobe AIR 19 Flex 4.6 iOS 9.02 ※AIRとかFlexとかバージョンが古いですが、
おそらくこれ以降のバージョンも同じに行けるはず。
Androidも同様にやればできるんですが、
iosのみをまとめておきます。

・注意点

Flashbilder4.6を利用しているとANEを作成後に
複数のANEを利用した時にデバッグ状態でエラーが出ます。
リリースして実機でやれば動きます。 このエラーは4.7を利用すれば治ります。

Qiita AIR for iOS で複数のANEを使うと、まったく使えなくなる場合がある

・手順について
AdobeのHPで紹介されている内容を参考に一部今風にしてます。
ネイティブ拡張(Native Extensions)入門 第2回 ネイティブ拡張の開発方法 前編


1:Xcodeでの作業

Xcodeでの作業は実現したい内容をスタティックライブラリを作る事になります。
Adobeのページのやり方をそのままやっていきます。
プロジェクトを作って、FlashRuntimeExtensions.hをコピーしてソースファイルを作る

ファイル1:ヘッダファイル
ヘッダには利用するライブラリと作る関数名を書いていきます。

---------------------------------------------------------------------
#import 
#import "FlashRuntimeExtensions.h"

@interface HelloWorldANE : NSObject

@end

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

void ContextInitializer(
                        void* extData,
                        const uint8_t* ctxType,
                        FREContext ctx,
                        uint32_t* numFunctionsToTest,
                        const FRENamedFunction** functionsToSet
                        );

void ContextFinalizer(FREContext ctx);


void ExtInitializer(
                    void** extDataToSet,
                    FREContextInitializer* ctxInitializerToSet,
                    FREContextFinalizer* ctxFinalizerToSet
                    );
void ExtFinalizer(void* extData);
---------------------------------------------------------------------

ソースファイル

---------------------------------------------------------------------
#import "HelloWorld.h"

@implementation HelloWorld

@end


FREObject GetHelloWorld(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]) {
    
    const char *str = "HelloWorld!";
    FREObject retStr;
    //FRENewObjectFromUTF8(strlen(str)+1, (const uint8_t *)str, &retStr);
    FRENewObjectFromUTF8((int)strlen(str)+1, (const uint8_t *)str, &retStr);
    
    return retStr;
}

void ContextInitializer(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;
}
void ContextFinalizer(FREContext ctx) {
    return;
}

void ExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet,
                    FREContextFinalizer* ctxFinalizerToSet) {

    *extDataToSet = NULL;
    *ctxInitializerToSet = &ContextInitializer;
    *ctxFinalizerToSet = &ContextFinalizer;
}
void ExtFinalizer(void* extData) {
    return;
}

---------------------------------------------------------------------

作成されたらビルドすることになるけど、
このとき、64ビット対応もしなくてはならないので
buidsettingから" valid architecture only "あたりでarm64 armv7 armv7sを選択しておく。

設定したらBuildとArchiveをしてスタチックファイルを取得する。


2:FlexBuilderでの作業

FlashProでもできるけど、Flashbuilderを使ったやり方が紹介されています。

ネイティブ拡張(Native Extensions)入門 第3回 ネイティブ拡張の開発方法 後編
FlexBuilderでの設定は上記ページのままでいけるが、
AIRの設定は修正しておく。

プロジェクトのプロパティを見る(右クリックとか)
Flexライブラリコンパイラを選択、追加コンパイラ引数を下記に設定

-locale en_US -swf-version=30

swfのバージョンは利用するAIRで変わってくる(今回はAIR19)

FlexBuilderで作ったANE呼び出しSWCのソース

---------------------------------------------------------------------
package net.kfactory
{
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.external.ExtensionContext;

	public class HelloWorld extends EventDispatcher{
		private var context:ExtensionContext;
		
		public function Helloworld(target:IEventDispatcher=null) {
			super(target);
			context= ExtensionContext.createExtensionContext("呼び出し用の名前", "type"); 
		}                                                    
	
		//追加 /////
		public function getHelloWorld():String {
			return context.call("GetHelloWorld") as String;
		}
	
		public function dispose():void {
			return context.dispose();
		}
	}
}
---------------------------------------------------------------------
呼び出し用の名前」は次に出てくるExtensionファイルで利用する


3:ANEの作成

ANEファイルはADTで作るが、その手順は下記が詳しい。
ネイティブ拡張(Native Extensions)入門 第3回 ネイティブ拡張の開発方法 後編
extensio.xmlファイル
---------------------------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?> <extension xmlns="http://ns.adobe.com/air/extension/19.0"> <id>呼び出し用の名前 <versionNumber>1.0.0 <platforms> <platform name="iPhone-ARM"> <applicationDeployment> <nativeLibrary>libHelloWorld.a <initializer>ExtInitializer <finalizer>ExtFinalizer </applicationDeployment> </platform> <platform name="default"> <applicationDeployment/> </platform> </platforms> </extension>
---------------------------------------------------------------------
※うまく表示できないので<を<で表示している
defalutは
Flashbuilder4.7とかでデバッグに利用したいなら設定しておく

4:ANEの作成2
extension.xmlができたら、XcodeのスタティックファイルとFlashbuilderで作ったANE呼び出しSWCを一緒におき、更に証明書を置いてADTでコンパイルする。

ADTの設定も上記のページで紹介されてます。
※実際は1行
adt 
-package 
-storetype pkcs12 
-keystore 証明書のファイル名(フルパス)
-target ane 作成するANEの名前 extension.xml
-swc 呼び出し用swcのファイル名 
-platform iPhone-ARM library.swf スタティックファイル名 
-platform default library.swf スタティックファイル名

platformではそれぞれのデバイス用に設定が行われる。
defaultがiphoneと同じにしているのはこちらの都合。


コンパイルがうまく行けばANEが作られる。


注意点はflashbulder4.6ではデバッグ実行時にスタティックファイルの関数名が見えないなどの問題がある。
実機では問題ないが面倒なので4.7を利用するといいかと。