多线程串口通讯ANE(ArduinoConnector)
本资源来自: ANE开源群 307700284
相关链接:
http://blog.163.com/longtimeno_c/blog/static/20493702620125141130409/
如何打包多线程串口通讯ANE
由 quetwo 编写的 as3-arduino-connector 多线程的串口通讯ANE是一个开源项目,在 GoogleCode 上面能下载到该ANE和相关的项目文件。
下载了ANE后,第一步就是测试她的功能了。 操作系统:WIN7 64bit 使用教程,在开源下载目录下作者就有简单而实用的介绍
按照原作者的指导,打开 Flash Builder 4.6 新建一个项目,直接在主函数上面添加上面的代码。把下载的ANE在该项目的src文件夹下面,再从项目——属性——构建路径——本机扩展中添加进去,注意在构建打包的本地扩展中也要打钩。 然后运行调试。 注意的是:调试运行过程中有可能出现: - ArgumentError: Error #3500: The extension context does not have a method with the name setupPort.
复制代码
上下文扩展找不到方法 setupPort
解决方法:在下载的ANE中解压出 pthreadGC2.dll 复制黏贴到 C:WindowsSystem32 和 C:WindowsSysWOW64 文件目录下即可。
成功调试后出现另一个问题,程序的串口接收端运行一段时间后停止接收,不能正常运行。 这个问题在下载ANE的网页上已经有人提出,原作者也给出了相应的解决方案:
按照描述在源项目的代码中添加作者提供的内容就可以解决问题。
有了方向,下一步就是改写项目文件。编程工具:Microsoft Visual Studio 2010 旗舰版新建一个 Visual C++ 下的 Win32 项目,应用程序类型 DLL 选择为空项目在原作者提供的网站下面有项目的源代码下载: 根据原作者提供的源代码,在自己的项目文件中建立相应(名字相同)的项目文件,代码直接复制黏贴。把作者提供的源代码都移到了自己的项目后,点击生成,发现弹出许多错误,原因需要我们手动添加进去。不过有了显示错误的地方,我们就能一个一个的去修改。
错误 1: error C1083: 无法打开包括文件:“FlashRuntimeExtensions.h”: No such file or directory f:libserialaneexampleexampleserialane.h 25 1 example
解决方案: 在路径 Adobe Flash Builder 4.6sdks.6.0includeFlashRuntimeExtensions.h 下复制该头文件,黏贴到项目文件目录下。只有头文件还不行,要有对应的库文件,因此在路劲 Adobe Flash Builder 4.6sdks.6.0libwinFlashRuntimeExtensions.lib 下把库文件也导入进去。然后在项目中的头文件文件夹中添加刚才导入的头文件,在资源文件栏中添加刚才导入的库文件。
重新生成,发现刚才的问题解决了,但又弹出更多的问题。
错误 2: error C1083: 无法打开包括文件:“pthread.h”: No such file or directory f:libserialaneexampleexampleserialane.c 25 1 example
解决方案: pthread 是一个多线程函数,在网站 http://sourceware.org/pthreads-win32/ 下可以下载到最新版本的 pthread 文件。我在项目中使用的是 pthreads-w32-2-9-1-release 。解压后可以得到3个文件夹 Pre-built.2 ,pthreads.2 和 QueueUserAPCEx 。打开 Pre-built.2include .里面有我们需要的头文件。把三个头文件都导入项目文件夹中(其中 semaphore.h 好像是没有用到的,但先加进去,谁知道运行过程中会发生什么)。头文件导入后就要导入库文件,在该网站中有关于库文件的命名的详细规范和作用,在这里,我使用的是 pthreadVC2.lib 。然后把刚才导入的项目文件都添加进项目中。
重新生成,pthread 有了,但提示无法打开 sched.h。
错误 3 error C1083: 无法打开包括文件:“sched.h”: No such file or directory f:libserialaneexampleexamplepthread.h 288 1 example
解决方案: 双击错误提示,转到错误地方。将 库调用改为 "sched.h" 本地调用即可。
再一次重新生成,会发现之前的问题解决了,但居然出现了令人崩溃的 151 个新的错误。。。。对,151个错误,要是真正一个一个的改好话,跟重新写一次程序没什么分别。但相信能作为开源项目发布上网,作者应该不会开这种玩笑吧,而且在问题哪里也没有发现有人提出(或许因为没人重写过),因此断定为应该是自己忽略了点什么。
但当认真的去一条条的看那些错误的时候,发现错误类型可以归纳为 语法错误;未声明标识符;下标要求数组和指针类型等的基础性的错误,而且数量如此之多,随后发现很多的未声明标识符并不是因为没有定义该方法,而是没有把函数的定义放在开头,于是怀疑文件类型是否不应该为C,于是把开始从网站上面复制过来的 SerialANE.c 和 rs232.c 的后缀名改为 .cpp 。
重新生成后问题果然减少了很多。然后同样的出现新的问题。
错误 4 error C2664: “pthread_create”: 不能将参数 3 从“void *(__cdecl *)(void)”转换为“void *(__cdecl *)(void *)” f:libserialaneexampleexampleserialane.cpp 266 1 example
解决方案: 双击错误提示,转到错误地方。根据提示,将 void *pollForData() 变为 void *pollForData(void*)。
点击重新生成,发现没有错误提示了,最后提示
========== 全部重新生成: 成功 1 个,失败 0 个,跳过 0 个 ==========
虽然编译完成,但先不修改代码,先打包ANE测试一下,看是否有问题。
附上最后生成时的项目文件目录:
.dll 的生成暂时就告一段落。
下一步就开始生成 ANE 了。本文中的是用 cmd 中的 binadt 命令打包 ANE 。但要生成可用的 ANE 还需要其他文件,以下博客中有详细说明: http://blog.sina.com.cn/s/blog_6471e1bb01012aql.html准备一个文件夹,用来存放打包ANE需要的文件。1.需要的是供给 AS 用的扩展库 SWC。打开 Flash Builder 4.6 新建一个 Flex库项目,按照原作者在网上提供的代码建立两个 .as 文件。(注意:包的名称必须完成按照原作者所提供的原代码的写法,在flash builder4.6 中需要在编译器附带参数中加入“-swf-version 13”否则打包ane时会出现Invalid swc file.The extension NameSpace requires the swf verison to be 13 or lower) AS文件的详细代码,在开源目录下已经提供:
完成后点击构建,在项目文件bin目录先就能找到对应的swc文件。
2.library.swf解压刚才生成的swc文件,就能得到两个文件,其中一个就是library.swf。(在生成ANE后,swc文件只是提供一个类似接口的作用,实际的函数是存储在swf文件里面,因此当需要修改AS文件的时候,必须重新解压一次新的swc文件,得出新的swf覆盖旧的swf。) 3.extension.xml 本机扩展描述性文件。
关于 extension.xml 的写法在开源目录下也有提供:
由于这次生成的平台只是 Windows 因此也对xml略改。只保留 Windows 的部分。
(注意:名字可以自己改,刚才生成的dll名称.dll XML可以用文本文件写然后改后缀,但要留意格式)
连同一开始生成的DLL文件,打包ANE最主要的4个文件到这步已经准备完成了。
4.打开Adobe Flash Builder 4.6sdks.6.0 ,在目录下复制 lib 和 bin 两个文件夹到该文件夹中,同时把 .12 文件也复制到该文件夹中(.p12文件可以是用任何一个 FL 或者 FB 生成的 .p12 文件)。
5.开始打包ANE。
运行命令行并将其路径设置到该文件夹路径上,然后键入:
bin/adt -package -storetype pkcs12 -keystore .p12文件名称.p12 -storepass .p12文件的密码 -target ane 需要生成的ane的名称.ane extension.xml -swc swc名称.swc -platform 平台名称 library.swf 本机扩展库
其中-platform有一下选项:
Android-ARM.(大伙们说这里要有".")
iPhone-ARM
MacOS-x86
Windows-x86
输入完毕,点击回车,完成ANE的生成。
接下来就是测试新的ANE。
把文本一开时用来测试下载的原ANE的 AS 项目重新拿出来,把原先使用的ANE从构建中删除,改为新的ANE,运行调试。
发现错误:
ArgumentError: Error #3500: The extension context does not have a method with the name setupPort.
DLL是成功生成了,ANE也成功打包了,但很严峻的问题出现了:新的ANE用不了。
在文章上面已经提到过了这个问题,原作者对这个问题的描述是:pthread.dll 应该是没有问题的,但程序初始化不了。
好吧。根据原作者的思路应该不存在于pthread.dll上面,那到底是哪里出错。
为了弄清楚到底哪里出错,想到了用排除法。
打包ANE所需要的7个文件,其中2个文件夹,1个p12文件是本机文件,应该不存在问题的。剩余的就是xml,swc,swf和dll文件。经过排除后判定。问题出现在自己生成的dll上面(用上了在开源目录上下载的dll配合其余文件打包得ANE能正常使用)。
既然把范围缩小到了DLL文件上面。那问题就是看到底DLL文件是哪里错。 在VS中能够成功编译并生成DLL,没有错误提示,而且全部代码是从开源项目中下载的。也就是说根本不知道从哪里入手。 通过与原DLL的对比后,发现自己的DLL大小只有原DLL大小的一半,但作者的项目内容都放在网上,都已经全部看过,他到底还加了些什么完全不知道。这时候。。。我想到了。。。既然源项目看不到,但起码他的DLL能用。。。那。。就反编译吧。。。虽然DLL的反编译是最难的,最不准确,与原代码相差最大的。。。但总聊胜于无吧。 于是从网上下载了一个 C/C++ 的反编译工具 W32Dasm 。 左边的是原DLL,右边的是自己生成的DLL:
对比发现两边DLL调用的DLL有不同。
不过对比发现一个之前有过的疑问:从源文件的复制,到DLL的生成再到ANE的打包都没有看到过pthreadGC2的身影,但在开源目录的提问下,却讲到了pthreadGC2的重要性,现在总算明白了,这东西在DLL生成的时候被同时打包进去(在Windows下添加进pthread.h是需要同时添加库目录,而库目录的类型就决定了之后该DLL调用的pthread DLL类型。而在Linux下是不需要手动添加pthread)
既然是这样,就让我联想到了,既然提问中的问题可以通过把该pthread过程.dll复制到系统文件下完成,那我DLL调用的是pthreadVC2.dll,之前复制的GC2应该对她没用,因此应该把VC2的复制进去,pthreadVC2.dll能在之前用过的pthreadVC2.lib的文件夹中找到。
重新调试,发现还是出现同样错误。
那应该还有别的错误。于是继续查看反编译后的文件。 果然又发现了一个问题: 左边原DLL,右边自己生成的DLL
扩展输出的函数名左边的正确显示,右边的却出现了乱码。 如果是因为初始化开始的函数一开始就不能被正确调用,那么之前一直出现的错误就说得通了,问题是,该要怎么改回来。 回想起之前从网上下来的源文件格式都是 .C 经过自己改回 .CPP 才被正常识别,那么这是同样的情况会不会又出现在头文件呢,但头文件 .h 是无论C还是C++都一样的,后缀就不可能的。 第一次是因为C编译对程序编写的要求高,因此以CPP格式写的文件不能被正确编译。这次道理应该也一样。 SerialANE.h中:
从这里发现 声明外部链接函数的写法不够规范,没有把编译方式写上,因此在两个函数的基础上添加了一句 extern "C" 然后重新生成DLL,打包ANE,添加进AS测试文件,调试运行——成功!!!! (最后,把该成功的DLL反编译一次后发现原先乱码的部分正确了;然后为了验证是否要在系统文件中添加对应的pthreadDLL文件,把原先在系统文件夹中的pthreadVC2.dll删除,重新运行,发现果然出了之前setport的错。)
这次要做的,是要解决那个一段时间后接受不了数据的问题。 回到该问题上,把作者提供的修改代码加上对应的地方后就可以,详细可以看本文开头。 好~~写完。 收工~~~
//-------------------------------------------------------------------------------------------------------------------------------------------------------//
补上 extern"C" 更改地方
|