2

私が抱えている質問は、sysAppLaunchCmdNormalLaunch 以外の起動コードでアプリを実行する場合、既定のコード セグメントの外側のコードを使用できませんが、マルチセグメント化された共有ライブラリを使用して、この問題を回避できますか?

ちょっとした背景情報: 私は、既存のモバイル アプリケーションを PalmOS に移植する可能性を評価しています。このアプリのコア部分は、バックグラウンドで 10 分程度ごとにネットワーク通信を行っていること、または受信データを (ネットワーク/ソケット コールバック経由で) 受信したときに実行していることです。この間、グローバルにアクセスできないため、アプリケーション内のデフォルト以外のコード セグメントにはアクセスできません。

現在の問題は、通信に関連するアクション (プロトコル、データ処理など) に大量のコードが必要であり、1 つのセグメントに収まらないことです。それだけ多くのコードを「バックグラウンド」で実行することに意味があるかどうかという問題は別として、明らかな問題は、そもそもどのように実行するかということです。したがって、コードを共有 (マルチセグメント) ライブラリに配置することが役立つかどうかという問題があります。

あなたの洞察を楽しみにしています。

4

2 に答える 2

2

共有ライブラリを使用した経験はありませんが、ソフトウェアでこの問題が発生し、問題を解決する 3 つの異なる方法に遭遇しました。

おそらく最も簡単なのは、Metrowerks コンパイラを使用するときに拡張モードを有効にすることですが、これが機能するかどうかは完全にはわかりません。この特別なモードを使用すると、非グローバル起動から呼び出されたときに、一定のグローバル データにアクセスできます。ただし、このアプローチを使用するには多くの注意事項があります。また、拡張モードで確実にセグメント間ジャンプができることを確認していません。Ben Combee によって書かれたホワイト ペーパーがあり、拡張モードの使用方法が詳細に説明されています。「Palm OS での拡張モードのサポート」というタイトルです。ウェブ上で見つけることができなかったので、私のウェブサイトにコピーを掲載しました: http://www.normsoft.com/tim/technical/Codewarrior_Expanded_Mode.pdf

もう 1 つのより複雑なオプションは、グローバルを自分でロードし、それらへのポインタを A5 に置くことです。これを行うには、グローバルをロードする Metrowerks スタートアップ コードを変更 (または複製) し、非グローバル起動を受け取ったときにこの変更されたコードを呼び出す必要があります。Metrowerks には、ランタイムのこの部分の完全なソースが含まれているため、非常に簡単に実行できますが、そのコードの一部は非常に難解です。私たちは、Pocket Tunes の 1 つのバージョンでこの手法を使用して、非グローバル起動コードから呼び出されたときにグローバルと無制限の数のセグメントにアクセスすることに成功しました。起動コードから戻るときは、必ず A5 を復元してください。

最後のオプションは、コードのすべて (または一部) を PNOlets に移動することです。コードを 68K と PNO にセグメント化する必要があるため、これは面倒です。この方法もうまく使用できましたが、インターワーキング コードのメンテナンスはひどいものでした。最終的に、PEAL ローダーを使用してコード全体を PNOlet に移動することになりました。これは、コードを 64KB のチャンクに自動的にセグメント化し、ARM コードをインプレースで実行するため、大きなコードに非常に適しています。ただし、PNOlet の開発は ARM で十分にサポートされていないため、これは非常に大きな労力になります。したがって、多くの低レベルのサポートを自分で提供する必要があります (各 API 関数を呼び出すためのサンクなど)。

于 2008-10-12T12:26:05.013 に答える
1

MemPtr で割り当てた大きな構造体へのポインタを、FtrSet を使用して 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;
}
于 2009-05-26T21:34:23.543 に答える