2008-10-11 2 views
2

질문 : sysAppLaunchCmdNormalLaunch 이외의 실행 코드로 내 앱을 실행할 때 기본 코드 세그먼트 외부에서 코드를 사용할 수 없지만 공유 코드를 사용할 수 있습니까? 라이브러리가 다중 세그먼트 화되어 있으므로이 문제를 피할 수 있습니까?다중 세그먼트 PalmOS 앱/라이브러리 "배경"

배경 정보 : 기존 모바일 애플리케이션을 PalmOS로 포팅 할 가능성을 평가하고 있습니다. 이 응용 프로그램의 핵심 부분은 10 분마다 또는 네트워크/소켓 콜백을 통해 들어오는 데이터를 수신 할 때 백그라운드에서 일부 네트워크 통신을 수행한다는 것입니다. 이 시간 동안 전역에 액세스 할 수 없으므로 기본 응용 프로그램 이외의 응용 프로그램에서 코드 세그먼트에 액세스 할 수 없습니다.

이제 문제는 통신 (프로토콜, 데이터 처리 등)에 관련된 작업이 단지 하나의 세그먼트에 들어 가지 않는 많은 코드를 필요로한다는 것입니다. 그 많은 코드가 '백그라운드'에서 실행되는 것이 타당한 가라는 질문과는 별도로 명백한 문제는 다음과 같습니다. 처음에 어떻게 실행합니까? 따라서 코드를 공유 (다중 세그먼트) 라이브러리에 넣을 지 여부가 문제가됩니다.

귀하의 통찰력을 기대하십시오.

답변

2

공유 라이브러리를 사용 해본 경험이 없지만 Google 소프트웨어에이 문제가 발생했습니다. 문제를 해결하는 세 가지 방법이 있습니다.

아마도 가장 쉬운 방법은 Metrowerks 컴파일러를 사용할 때 확장 모드를 설정하는 것이지만 이것이 제대로 작동하는지 완전히 확신 할 수는 없습니다. 이 특수 모드를 사용하면 전역이 아닌 시작에서 호출 할 때 특정 상수 전역 데이터에 액세스 할 수 있습니다. 그러나이 방법을 사용하는 데는 많은주의가 필요합니다. 또한 확장 모드가 세그먼트 간 점프를 허용한다는 것을 확인하지 못했습니다. 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 코드를 내부에서 실행하기 때문에 대용량 코드에서 효과적입니다. 그러나 PNOlet 개발은 ARM에서 잘 지원되지 않으므로 매우 많은 노력이 필요합니다. 따라서 각 API 함수를 호출하기위한 썽크 (thunks)와 같이 직접 많은 저수준 지원을 제공해야합니다.

+0

고맙습니다. PNOlets 사용에 대해 생각하고 있었지만 불행히도이 프로젝트의 시간 제한이 너무 길어서 많은 실험을 할 수 없었습니다. 그러나 PEAL은 매우 재미있어 보인다! 또한 포드 (또는 gcc)를 사용하려고했기 때문에 CW의 확장 모드가 나를 도와주지 않을 것입니다. ;-) – Steven

+0

좋은 대답, 팀 ... 내가 쓴 것보다 낫다! –

0

FtrSet을 사용하여 Ftr 메모리에 MemPtr과 할당 한 멋진 대형 구조체에 대한 포인터를 저장하십시오. 이것은 FtrGet을 사용하여 전역 액세스가 필요한 응용 프로그램의 어느 위치에서나 검색 할 수 있습니다.

__STANDALONE_CODE_RESOURCE__을 사용하여 각 기능을 별도의 코드 세그먼트에 넣고 래퍼와 함께 shared.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; 
} 
+0

작업이 끝나면 핸들을 잠금 해제해야합니다. MemHandleUnlock (H); – PhrkOnLsh