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传会过来的数据。
大功告成!