我的第一个ANE程序

ANE的全称是Adobe Native Extensions。
 
相信很多人都听过ANE,它是AIR功能的一个扩展。利用ANE能实现AIR不能实现的功能。现在ANE广泛的被应用到AIR开发的IOS和Andriod程序里。
 
但是ANE实现起来确实相当的麻烦,为了写一个ANE程序,至少要建3个项目。
 
现在来介绍下我的第一个成功的ANE程序。
 
这个程序是AIR调用DLL里面的方法,弹出消息框,并将参数传到DLL的方法里,显示在弹框上。 同时又将返回的数据显示在AIR程序里。
 
 
1、创建一个C++动态链接库项目。
 
由于电脑上没装VC++所以我就下了个Code::Blocks作为我的C++开发环境。
然后新建个Dynamic Link Library项目。命名为AneDLLs
目录如下:
在main.h里面添加如下代码:
#ifndef __MAIN_H__
#define __MAIN_H__
 
#include <windows.h>
#include "FlashRuntimeExtensions.h"
 
/*  To use this exported function of dll, include this header
 *  in your project.
*/
 
#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif
 
#ifdef __cplusplus
extern "C"
{
#endif
 
    FREObject DLL_EXPORT myFunc1(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]);
    void DLL_EXPORT initializer(void** extData, FREContextInitializer* ctxInitializer, FREContextFinalizer* ctxFinalizer);
    void DLL_EXPORT finalizer(void* extData);
 
#ifdef __cplusplus
}
#endif
 
#endif // __MAIN_H__
myFunc1是我自己添加的函数供flash调用的。
在main.cpp里面添加如下代码:
#include "main.h"
#include "FlashRuntimeExtensions.h"
 
extern "C"
{
    char* UTF8ToGBK(const char* strUtf8)
    {
        int len=MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, NULL,0);
        unsigned short * wszGBK = new unsigned short[len+1];
        memset(wszGBK, 0, len * 2 + 2);
        MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, (LPWSTR)wszGBK, len);
        len = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wszGBK, -1, NULL, 0, NULL, NULL);
        char *szGBK=new char[len + 1];
        memset(szGBK, 0, len + 1);
        WideCharToMultiByte (CP_ACP, 0, (LPCWSTR)wszGBK, -1, (LPSTR)szGBK, len, NULL,NULL);
        return szGBK;
    }
 
    char* GBKToUTF8(const char* strGBK)
    {
        int len=MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, NULL,0);
        unsigned short * wszUtf8 = new unsigned short[len+1];
        memset(wszUtf8, 0, len * 2 + 2);
        MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, (LPWSTR)wszUtf8, len);
        len = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)wszUtf8, -1, NULL, 0, NULL, NULL);
        char *szUtf8=new char[len + 1];
        memset(szUtf8, 0, len + 1);
        WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)wszUtf8, -1, (LPSTR)szUtf8, len, NULL,NULL);
        return szUtf8;
    }
 
    FREObject myFunc1(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[])
    {
        const uint8_t *str = 0;
        uint32_t len;
        const char *a = NULL;
 
        if(FRE_OK == FREGetObjectAsUTF8(argv[0], &len, &str)) {
            a = UTF8ToGBK((const char*)str);
        }else{
            a = "这个是默认的!";
        }
 
        MessageBoxA(0, a, "DLL Message", MB_OK | MB_ICONINFORMATION);
 
        const char *resultString = GBKToUTF8("这个是Dll的返回结果!");
        FREObject freObj = NULL;
        FRENewObjectFromUTF8(strlen(resultString),(const uint8_t*)resultString, &freObj);
        return freObj;
    }
 
    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*) "myFunc1";
        func[0].functionData = NULL;
        func[0].function = &myFunc1;
 
        *functions = func;
    }
 
    void contextFinalizer(FREContext ctx)
    {
        return;
    }
 
    void initializer(void** extData, FREContextInitializer* ctxInitializer, FREContextFinalizer* ctxFinalizer)
    {
        *ctxInitializer = &contextInitializer;
        *ctxFinalizer = &contextFinalizer;
    }
 
    void finalizer(void* extData)
    {
        return;
    }
}
UTF8ToGBK和GBKToUTF8函数是为了解决as和c++交互时中文出现乱码的问题。(C++用的是gbk编码,flash用的是utf8编码)
 
在FlashBuilder的安装路径里找到 FlashRuntimeExtensions.h 文件(我的路径是D:\Program Files\Adobe\Adobe Flash Builder 4.6\sdks\4.6.0\include)放到刚才的C++项目里。
同样 在FlashBuilder的安装路径里找到 FlashRuntimeExtensions.lib 文件(我的路径是D:\Program Files\Adobe\Adobe Flash Builder 4.6\sdks\4.6.0\lib\win)放到刚才的C++项目里。
然后吧 FlashRuntimeExtensions.lib 链接到C++项目里。
 
编译项目就会生成一个叫AneDLLs.dll文件,把这个文件复制出来,后面要用到。
 
 
2、创建一个Flex或AS库项目。
 
在FlashBuilder里新建一个库项目。命名为AneTestLib。
新建一个Class文件 CallDllFunc.as,里面添加两个函数:
public function CallDllFunc()
{
    context = ExtensionContext.createExtensionContext("myDll1""");
}
 
public function test1Func(value:String):String
{
    var obj:* = context.call("myFunc1", value)
    return  obj;
}
这里面的myFunc1就是上面dll里面定义的函数。然后编译项目生成一个叫AneTestLib.swc的文件。
将swc文件copy到刚才dll文件所在的目录里。用解压缩工具打开swc文件将里面的连个文件library.swf和catalog.xml复制出来放到同一目录下。
新建个extension.xml文件,放入一下内容:
<extension xmlns="http://ns.adobe.com/air/extension/2.5">
    <id>myDll1</id>
    <versionNumber>1.0.0</versionNumber>
    <platforms>
        <platform name="Windows-x86">
            <applicationDeployment>
                <nativeLibrary>AneDLLs.dll</nativeLibrary>
                <initializer>initializer</initializer>
                <finalizer>finalizer</finalizer>
            </applicationDeployment>
        </platform>
    </platforms>
</extension>
<id>myDll1</id>里面的值要跟库项目里createExtensionContext里用到的值相同。
<nativeLibrary>AneDlls.dll</nativeLibrary>里面的值就是刚才生成的dll文件的名称。
然后用FlashBuilder创建一个整数文件我创建的是test1_test.p12 用户名-密码 是 test1-test。此文件打包时要用到。
新建个package.bat文件里面添加:
"D:\Program Files\Adobe\Adobe Flash Builder 4.6\sdks\4.6.0\bin\adt.bat" -package -tsa none -storetype pkcs12 -keystore test1_test.p12 -storepass test -target ane LibAne.ane extension.xml -swc AneTestLib.swc -platform Windows-x86 library.swf AneDLLs.dll
这个bat文件是用来生成ane的。里面的参数相信大家都能看懂。不懂的百度下就明白了。
 
运行bat后会生成一个LibAne.ane的文件。至此ane文件已经生成了。你已经完成了2/3的工作。后面就很简单了。
 
 
3、创建一个AIR项目。
 
用FlashBuilder创建一个AIR项目。将刚才生成的ane文件导入到项目里。
在主文件里添加一个按钮。加上按钮click事件。在事件里添加:
var call:CallDllFunc = new CallDllFunc();
trace(call.test1Func("这个是flash传过去的数据!"));
 
运行程序:
点击程序里的按钮,就会看到一个信息窗口。关闭窗口后,会在FlashBuilder的控制台里看到dll传会过来的数据。
 
 
大功告成!
posted @ 2013-02-28 16:44  火苗_IT  阅读(2109)  评论(1编辑  收藏  举报