我遇到的问题是:当使用除sysAppLaunchCmdNormalLaunch之外的启动代码运行我的应用程序时,我无法使用默认代码段之外的代码 - 但我可以使用多分段的共享库,从而避免这个问题?
一些背景信息:我正在评估将现有移动应用程序移植到PalmOS的可能性。这个应用程序的核心部分是它每隔10分钟左右在后台进行一些网络通信,或者当它接收传入数据时(通过网络/套接字回调)。在此期间,我没有访问全局变量,因此不能访问我的应用程序中的任何代码段而不是默认代码段。
现在的问题是通信中涉及的操作(协议,数据处理等)需要大量不适合一个段的代码。除了在“背景”中运行那么多代码是否合理的问题之外,显而易见的问题是:我如何首先运行它?因此,将代码放在共享(多段)库中的问题会有所帮助。
期待您的见解。
答案 0 :(得分:2)
我没有使用共享库的经验,但我们的软件遇到了这个问题,我们遇到了三种不同的方法来解决这个问题。
最简单的方法是在使用Metrowerks编译器时启用扩展模式,但我不完全确定这是否有效。此特殊模式允许您在从非全局启动调用时访问某些常量全局数据。但是,使用这种方法有很多警告。另外,我还没有确认Expanded Mode可以确保段间跳转。 Ben Combee写了一份白皮书,详细解释了如何使用扩展模式。它的标题是“支持Palm OS上的扩展模式”。我在网上找不到它,所以我在我的网站上贴了一份:http://www.normsoft.com/tim/technical/Codewarrior_Expanded_Mode.pdf
另一个更复杂的选择是自己加载全局变量并在A5中添加指针。为此,您必须修改(或复制)加载全局变量的Metrowerks启动代码,然后在收到非全局启动时调用此修改后的代码。 Metrowerks包含运行时的这一部分的完整源代码,因此您可以非常轻松地完成此操作,尽管其中一些代码非常神秘。我们在一个版本的Pocket Tunes中成功地使用了这种技术,以便在从非全局启动代码调用时访问全局变量和无限数量的段。从发布代码返回时,请务必恢复A5。
最后一个选项是将所有(或部分)代码移动到PNOlet中。这可能很痛苦,因为您必须将代码分割为68K和PNO,这很快就会成为维护的噩梦。我们也成功地使用了这种方法,但是互通代码的维护非常糟糕。我们最终使用PEAL加载器将整个代码移动到PNOlet,这对于大型代码非常有效,因为它会自动将代码分段为64KB块并就地运行ARM代码。但是,这是一项非常大的工作,因为在ARM上没有很好地支持PNOlet开发,所以你必须自己提供很多低级支持(比如调用每个API函数的thunks)。
答案 1 :(得分:1)
使用FtrSet存储指向使用Memtrtr在Ftr内存中分配的漂亮大型结构的指针。可以使用FtrGet在需要全局访问的应用程序中的任何位置检索此内容。
或者使用__STANDALONE_CODE_RESOURCE__
将每个函数放入一个单独的代码段中,并使用带有包装器的共享functions.c来加载并锁定它们到内存中来调用它们。
//segment 1000
UInt32 foobar( char* hi )
{
return 12;
}
// functions.c
typedef (UInt32)(*fooPtr)( char* ); // this is now a type representing a pointer to your function.
UInt32 foobar( char* hi )
{
LocalID id; UInt16 cn; SysCurAppDatabase(&cn,&id);
DmOpenRef ref = DmOpenDatabase (cn, id, dmModeReadOnly );
MemHandle H = DmGetResource('code',1000);
fooPtr code = MemHandleLock(H);
UInt32 result = (*fooPtr)( hi);
return result;
}