Flash and C++ Native Extension速習

# 参照
 * http://rhuno.com/flashblog/2012/04/30/tutorial-flash-and-c-native-extension
 * http://rest-term.com/archives/2950/
 * http://www.adobe.com/jp/devnet/air/articles/native_extensions_part1.html

# ツール
 * windows7
 * Flex SDK 4.6
 * Visual studio Express 2012

# 関連ライブラリ
 * [Native extension descriptor files]("http://help.adobe.com/en_US/air/extensions/WSf268776665d7970d-2e74ffb4130044f3619-8000.html")
 * [ExtensionContext - AS3]("http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExtensionContext.html")
 * [Native C API Reference]("http://help.adobe.com/en_US/air/extensions/WSb464b1207c184b14-62b8e11f12937b86be4-8000.html")
 * [Coding the native side with C]("http://help.adobe.com/en_US/air/extensions/WS460ee381960520ad-866f9c112aa6e1ad46-8000.html")

# 手順

## DLLファイル作成

#### C++ project作成
  1. ファイル　→　新しいプロジェクト
  1. インストール済み　→　テンプレート　→　win32プロジェクト
  1. プロジェクト名：　NativeRemove
  1. 「OK」ボタンを押す
  1. 「次へ」ボタンを押す
  1. アプリケーションの設定
   * アプリケーションの種類：　DLL
  1. 「完了」ボタンを押す

#### プロジェクトに関するファイル修正
  1. dllmain.cpp

     ```
○　#include <Windows.h>
×　#include "stdafx.h" 
```

  1. 以下のファイルを削除

     ```
stdafx.h
stdafx.cpp 
targetver.h
```

  1. NativeRemove.hを新規

    ```c
#include "FlashRuntimeExtensions.h"  
extern "C"  
{  
  __declspec(dllexport) void ExtInitializer(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet);  
  
  __declspec(dllexport) void ExtFinalizer(void* extData);  
  
  __declspec(dllexport) FREObject doRemove(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]);  
}  
```

#### flashに関するファイル追加

 * FlashRuntimeExtensions.h
  * Flex SDK/include/から、NativeRemoveプロジェクトにコピーして、ヘッダファイルとして項目追加
 * FlashRuntimeExtensions.lib
  * NativeRemoveプロジェクトから、Flex SDK/lib/winから、項目追加

#### NativeRemoveプロジェクト設定変更

 * プロジェクトに右キーをクリックして、プロパティをクリック
 * 構成プロパティ　→　C/C++ →　プリコンパイル済みヘッダー
 * 「プリコンパイル済みヘッダーを使用しない」に変更

#### flash用C++メソッド実装

```cpp
// NativeRemove.cpp : Defines the exported functions for the DLL application.  
   
#include "NativeRemove.h"  
#include <stdlib.h>  

extern "C" 
{  
  FREObject doRemove(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[])   
  {  
    int32_t one, two, sum;  
    FREObject result;  
   
    FREGetObjectAsInt32(argv[0], &one);  
    FREGetObjectAsInt32(argv[1], &two);  
   
    sum = one - two;  
   
    FRENewObjectFromInt32(sum, &result);  
   
    return result;  
  }  
   
  void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, uint32_t* numFunctions, const FRENamedFunction** functions)  
  {  
    *numFunctions = 1;  
    FRENamedFunction* func = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*(*numFunctions));  
       
    func[0].name = (const uint8_t*)"doRemove";  
    func[0].functionData = NULL;  
    func[0].function = &doRemove;  
   
    *functions = func;  
  }  
   
  void ContextFinalizer(FREContext ctx)   
  {  
    return;  
  }  
   
  void ExtInitializer(void** extData, FREContextInitializer* ctxInitializer, FREContextFinalizer* ctxFinalizer)   
  {  
    *ctxInitializer = &ContextInitializer;  
    *ctxFinalizer   = &ContextFinalizer;  
  }  
   
  void ExtFinalizer(void* extData)   
  {  
    return;  
  }  
}
```

#### NativeRemove.dll作成
 * プロジェクトを選択して、ビルド


## ANE作成

#### workspaceを作成
 * C:\workspace\flash_native_remove

#### NativeRemove.asファイルを作成

```as3
package com.yan   
{  
  import flash.events.EventDispatcher;  
  import flash.external.ExtensionContext;  
    
  public class NativeRemove extends EventDispatcher  
  {  
    private var _ctx:ExtensionContext;  
          
    public function NativeRemove()   
    {  
      _ctx = ExtensionContext.createExtensionContext('com.yan.NativeRemove', '');  
    }  
          
    public function doRemove(a:int, b:int):int  
    {  
      var result:int;  
      result = _ctx.call('doRemove', a, b) as int;  
      return result;  
    }  
          
    public function dispose():void  
    {  
      _ctx.dispose();  
    }     
  }  
}
```

#### com.yan.NativeRemove.swcファイル作成

```shell-session
C:\workspace\flash_native_remove>acompc -source-path ./ -include-classes com.yan.NativeRemove -swf-version=14 -output com.yan.NativeRemove.swc
```

#### extdesc.xmlファイル作成

```xml
<extension xmlns="http://ns.adobe.com/air/extension/3.1">   
    <id>com.yan.NativeRemove</id>   
    <versionNumber>1</versionNumber>   
    <platforms>   
        <platform name="Windows-x86">   
            <applicationDeployment>   
                <nativeLibrary>NativeRemove.dll</nativeLibrary>  
                <initializer>ExtInitializer</initializer>  
                <finalizer>ExtFinalizer</finalizer>  
            </applicationDeployment>  
        </platform>   
    </platforms>   
</extension>
```

#### extfilesフォルダを作成
 * C:\workspace\flash_native_remove\extfiles

#### library.swf取得
 * com.yan.NativeRemove.swcから、com.yan.NativeRemove.zipに変更して、解凍
 * library.swfをextfilesに移動

#### 以下のファイルもextfilesに移動
 * extdesc.xml
 * NativeRemove.dll
 * com.yan.NativeRemove.swc
 
#### NativeRemove.ane作成

```shell-session
C:\workspace\flash_native_remove>adt -package -target ane NativeRemove.ane extfiles/extdesc.xml -swc extfiles/com.yan.NativeRemove.swc
-platform Windows-x86 -C extfiles NativeRemove.dll library.swf
```

## flashで実行

#### NativeRemove.aneファイル設定
 1. NativeRemove.aneファイルをNativeRemove.swcにrenameする
 1. C:\workspace\flash_native_remove\下に、extension\release\とextension\debug\フォルダを作成
 1. NativeRemove.swcをextension\release\にコピーして、NativeRemove.aneにrenameする
 1. NativeRemove.swcをextension\debug\にコピーして、NativeRemove.zipにrenameして、解凍する
 1. 展開してフォルダのネームをNativeRemove.aneに変更

#### helloane.mxml作成

```xml
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" title="hello air">
  <mx:Script>
    <![CDATA[
      import com.yan.NativeRemove;
      private function button_click():void {
        var ane:NativeRemove = new NativeRemove();              
        var sum:int = ane.doRemove(10, 5);    
        ane.dispose();  
        mx.controls.Alert.show(sum.toString(), "message");
      }
    ]]>
  </mx:Script>
  <mx:Label text="name: "/>
  <mx:TextInput text="input your name"/>
  <mx:Button label="send" click="button_click()"/>
</mx:WindowedApplication>
```

#### helloane.swf作成

```shell-session
C:\workspace\flash_native_remove>amxmlc helloane.mxml
```

#### helloane-app.xml作成

```xml
<?xml version="1.0" encoding="UTF-8"?> 
<application xmlns="http://ns.adobe.com/air/application/3.1" minimumPatchLevel="0"> 
    <id>examples.html.HelloWorld</id> 
    <versionNumber>1</versionNumber>
    <filename>helloAIR</filename> 
    <initialWindow> 
        <content>helloane.swf</content> 
        <visible>true</visible> 
        <width>400</width> 
        <height>200</height> 
    </initialWindow>
    <supportedProfiles>extendedDesktop</supportedProfiles>  
    <extensions>  
      <extensionID>com.yan.NativeRemove</extensionID>  
    </extensions>  
</application>
```

#### 実行して、結果表示

```shell-session
C:\workspace\flash_native_remove>adl helloane-app.xml -extdir extension\debug\
```

![flash_native_remove_result.png](https://qiita-image-store.s3.amazonaws.com/0/13451/f942058b-6f66-33e2-81ae-ada10d8e0b95.png)

# つづく
 * 各実装したファイル内容を説明する