Trao đổi với tôi

http://www.buidao.com

11/28/10

[Symbian] Lập trình với Symbian OS P2


Quản lý các tệp thực thi trên Symbian

* Tệp thực thi
Trên Symbian hỗ trợ 2 hệ thống chương trình thực thi với các kiểu file khác nhau:
+ Chương trình .exe: được lưu trữ trong các file thực thi có phần mở rộng là exe. Đây là chương trình với một đầu vào chính từ hàm E32Main(). Khi hệ thống nạp một chương trình .exe mới, đầu tiên nó tạo một tiến trình mới. Trong tiểu trình chính của tiến trình này, điểm vào sẽ được gọi để thực thi chương trình đó. Thông thường đây là các server hay các ứng dụng console.
+ Thư viện liên kết động (Dynamic link library-DLL): một thư viện chứa các mã chương trình với nhiều điểm đầu vào. Hệ thống sẽ nạp một DLL vào trong ngữ cảnh hoạt động của tiểu trình. Có 2 loại DLL quan trọng:
- Shared DLL: cung cấp một nhóm API nhất định cho một hay nhiều chương trình sử dụng. Hầu hết các thư viện này nằm trong các file có phần mở rộng là .dll. Một chương trình thực thi sẽ được nối với thư viện dùng chung mà nó yêu cầu và khi hệ thống nạp chương trình thực thi, thư viện dùng chung cần cho chương trình này sẽ được nạp tự động.
- Polymorphic DLL: Cung cấp một nhóm hàm API được lưu trữ trong các file có phần mở rộng khác nhau phục vụ cho các chức năng riêng như điều khiển máy in (.prn), giao thức socket (.prt), hay đó là một ứng dụng đồ họa GUI (.app). Trong hệ điều hành Symbian, polymorphic DLL thường chỉ có một điểm vào, nó khai báo và khởi tạo một lớp dẫn xuất từ các lớp cơ sở trong DLL này. Thư viện DLL loại này được nạp bởi chương trình sử dụng nó.

Chú ý: Chương trình .exe là không thể chia sẻ trong khi DLL thì hoàn toàn có thể.

* Nạp chương trình khi thực thi
Trong Symbian thì ổ C chính là RAM, ổ Z là ROM và thẻ nhớ thường là ổ D hoặc E.
+ Chương trình .exe: Một chương trình .exe được lưu trữ ở RAM hoặc trên thẻ nhớ, khi chạy, chương trình sẽ được nạp vào RAM, được cấp một vùng nhớ riêng cho mã, dữ liệu chỉ đọc, dữ liệu động. Nếu một phiên bản thứ 2 của chương trình được nạp vào RAM thì một vùng nhớ mới sẽ được cấp cho nó. Với file chương trình .exe chứa trong ROM thì chỉ có dữ liệu động được nạp vào RAM, mã chỉ thị và dữ liệu chỉ đọc được đọc trực tiếp từ ROM.
+ Thư viện DLL: Khi một thư viện DLL lần đầu tiên được nạp vào RAM, nó được cấp một vùng nhớ riêng, khi được yêu cầu sử dụng lần thứ hai, nó không nạp tiếp DLL này vào RAM mà đơn giản chỉ gắn địa chỉ nó trên RAM cho tiểu trình yêu cầu. Hệ điều hành Symbian kiểm tra số lượng tiểu trình tham khảo DLL này và giải phóng nó khi không còn tiểu trình nào sử dụng nó nữa. Đó là lý do mà các ứng dụng đồ họa Symbian (một loại polymorphic DLL), không hề có chức năng exit, nhất là các ứng dụng hệ thống vì việc thoát nó sẽ do hệ thống đảm trách khi thiếu RAM cho các ứng dụng khác) Với các DLL chứa trên ROM thì nó không cần nạp vào RAM nữa mà được sử dụng trực tiếp trên ROM.
=> Việc các ứng dụng lưu trữ trên ROM không cần nạp vào RAM khi thực thi là đặc điểm của Symbian để phù hợp với tài nguyên bộ nhớ giới hạn của điện thoại. Ngoài ra để tối ưu hóa kích thước chương trình, hệ điều hành Symbian sử dụng điểm vào của DLL là một số thứ tự, trên các hệ điều hành khác có thể dùng số thứ tự hay tên. Do đó khi nâng cấp DLL thì số thứ tự phải giống như phiên bản trước.

* Server và việc thực thi ứng dụng
+ Các server được lưu trữ trong các file .exe, như ewsrv.exe là window server, hay efsrv.exe là file server. Để giảm chi phí chuyển đổi ngữ cảnh các server có cùng nhóm chức năng được dùng chung một tiến trình. Một server chính sẽ tạo tiến trình và các server khác sẽ thực thi tiểu trình của nó với tiểu trình của server chính.
+ Ứng dụng console (không có giao diện đồ họa) được thực thi qua file chương trình .exe. Các ứng dụng dạng này phải tạo một console riêng để tương tác với người dùng.
+ Các ứng dụng có giao diện đồ họa (GUI) là những thư viện polymorphic DLL với phần mở rộng là .app. Điểm vào của ứng dụng này là NewApplication() tạo và trả về một đối tượng dẫn xuất từ lớpCEikApplication (Series 80/9200Series/Series90) hay các lớp dẫn xuất từ CEikApplication phù hợp theo từng dòng điện thoại Symbian như CQikApplication (UIQ), CAknApplication (Series 60). Tiến trình ứng dụng được tạo bởi một chương trình nhỏ .exe, Apprun.exe, và tên của file chương trình ứng dụng .app được chuyển làm tham số cho Apprun.exe.

* Định danh tệp
Symbian không quản lý các file dựa trên tên và phân biệt loại file dựa trên phần mở rộng như các hệ điều hành khác vẫn làm mà quản lý dựa trên một tổ hợp 3 số 32-bit. Mỗi một số như vậy được gọi là định danh tệp (Unique Identifier - UID). UID được dùng để phân biệt và xác nhận, chọn lựa đúng các loại đối tượng khác nhau tại thời điểm nạp và thực thi, như phân biệt ứng dụng console, DLL, server, v.v... UID cũng là thành phần cơ bản để liên kết ứng dụng với tài liệu, ví dụ tài liệu ứng với một ứng dụng sẽ yêu cầu hệ thống nạp ứng dụng khi tài liệu đó được mở.

Ba UID này (UID1, UID2 và UID3) có giá trị hằng ứng với các tên gọi do Symbian quy định, nhưng cũng có thể sử dụng số hệ 10 hay hệ 16.
- UID1: Định danh cấp hệ thống, chương trình thực thi .exe hay DLL được phân biệt nhờ UID1. Với các giá trị tương ứng KExecutableImageUid=0x1000007AKDynamicLibraryUid=0x10000079.
- UID2: Định danh cấp giao tiếp, phân biệt các đối tượng cùng UID1. Ví dụ, UID2 được dùng để phân biệt thư viện dùng chung .dll và thư viện polymorphic (như .app, .mdl, .fep hay .ctl) qua các giá trị:KSharedLibraryUid=0x1000008d cho thư viện dùng chung và KUidApp=0x100039CE cho một ứng dụng đồ họa .app, recognizer(auto start)=0x10003A19, front-end procesors=0x10005E32, hay control panel=0x10003A34.
- UID3: Định danh cấp chương trình thực thi, phân biệt các đối tượng có cùng UID2, chẳng hạn các ứng dụng đồ họa khác nhau sẽ có UID3 khác nhau. Do đó, có một tổ chức quản lý UID3 này cho toàn môi trường Symbian. Để có nó, lập trình viên phải gởi mail về uid@symbiandevnet.com để xin một số UID3 duy nhất trên môi trường Symbian.
=> Tổ hợp 3 số UID sẽ là duy nhất trên toàn môi trường Symbian. Nếu bạn sử dụng UID3 tùy tiện thì chương trình của bạn vẫn có thể chạy được nhưng nếu trên 1 máy nào đó có sẵn chương trình khác cùng loại và có cùng UID3 (nghĩa là trùng cả 3 số) thì chương trình của bạn sẽ không chạy vì chương trình cài trước đó sẽ được ưu tiên.

Một đối tượng hay một file trong Symbian có thể có một, hai, ba hay không cần UID.
- Để sử dụng thuận tiện trong việc tương tác và chuyển đổi dữ liệu với các hệ thống khác, hệ điều hành cho phép không cần sử dụng UID. Khi không có UID, Symbian sẽ phân biệt dựa vào quy ước đặt tên.
- Ứng dụng thực thi .exe thường chỉ có UID1 với giá trị KExecutableImageUid.
- Ứng dụng DLL: Các ứng dụng này có UID1 là KDynamicLibraryUid. Với các thư viện dùng chung .dll, UID2 sẽ là KSharedLibraryUid. Với các thư viện polymorphic, UID2 sẽ có nhiều giá trị khác nhau tùy từng loại. UID3 thì các DLL hầu như không cần, chỉ có các loại thư viện polymorphic là cần đến.
- Đối với các loại tài liệu thì UID1 là KDirectFileStoreLayoutUid hoặc KPermanentFileStoreLayoutUid ứng với tài liệu độc lập và tài liệu cơ sở dữ liệu. UID2 và UID3 phụ thuộc ứng dụng mà tài liệu phục vụ.
=> Vì UID là giá trị được sử dụng để phân biệt nên cần sự chính xác. Đối với UID3 dùng trong ứng dụng đồ họa, trong quá trình phát triển, có thể sử dụng một giá trị bất kỳ trong khoảng 0x010000000x0fffffff. Nhưng khi cài ứng dụng vào điện thoại thì nhất định đó phải là con số được cấp chính xác và duy nhất.


Cấu trúc Project trên Symbian OS

Thông thường các project được xây dựng trên các IDE hỗ trợ nhưng trên Symbian thì khác. Vì có nhiều loại điện thoại, nhiều nền hệ thống và nhiều bộ công cụ phát triển khác nhau nên hệ điều hành Symbian đã cho phép project được đặc tả trong một định dạng độc lập. Sau đó, với các công cụ đi kèm trong các bộ công cụ phát triển hay trên các IDE hỗ trợ, các file project này được định dạng lại thành các file project phù hợp với IDE cho dòng điện thoại cụ thể và bộ SDK cho điện thoại đó.

* File định nghĩa project (.mmp)
File này mô tả các thông tin của project. Đây là một file project độc lập, nó sẽ được chuyển thành file phù hợp môi trường phát triển cụ thể với các công cụ makmake hay lệnh abld.bat. Nó định nghĩa các file tài nguyên và file thông tin ứng dụng cần cho quá trình biên dịch.
Cấu trúc file .mmp gồm: các dòng khai báo với các loại câu khai báo khác nhau. Thông thường chỉ một số ít khai báo được dùng. Sau đây là cú pháp các khai báo thông dụng qua ví dụ project HelloWorld với fileHelloWorld.mmp:
- Aif:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
aif target-file source-path resource [color-depth] source-bitmap-list

Với:
target-file: Tên file đích, thường viết luôn phần đuôi và nằm trong thư mục ứng dụng.
source-path: Đường dẫn đến nơi chứa file tài nguyên mà aif cần
resource: Tên các file tài nguyên mà aif cần với tên đầy đủ.
color-depth: Đặc tả cho tất cả các file bitmap và ở dạng [c][digit] với c là color bitmap và "digit" thể hiện độ sâu.

Ví dụ:
MÃ: CHỌN TẤT CẢ
aif helloworld.aif \helloworld\aif\ helloaif.rss c8 hello.bmp hellom.bmp

- Target:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
target filename.ext

Ví dụ:
MÃ: CHỌN TẤT CẢ
target HelloWorld.app

- TargetType:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
targettype target-type

Với target-type được hỗ trợ bao gồm: ani, app, ctl, dll, ecomiic, epocexe, exe, exedll, fsy, kdll, kext, klib, ldd, lib, mda, mdl, notifier, opx, pdd, pdl rdl, var, wlog.
Ví dụ:
MÃ: CHỌN TẤT CẢ
targettype app

- UID:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
uid uid2 [uid3]

Mỗi ứng dụng thực thi có 3 loại UID, UID thứ nhất là targettype ở trên. Loại thứ hai và thứ ba là tùy chọn. UID được viết dưới dạng số hệ 10 hoặc hệ 16.
Ví dụ:
MÃ: CHỌN TẤT CẢ
uid 0x100039CE 0x10004299

- TargetPath:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
targetpath target-path

Ví dụ:
MÃ: CHỌN TẤT CẢ
targetpath \system\apps\HelloWorld

- SourcePath:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
sourcepath directory

Có thể có nhiều sourcepath nhưng đối với file mã và tài nguyên công cụ biên dịch chỉ quan tâm đến trong khai báo sourcepath cuối cùng.
Ví dụ:
MÃ: CHỌN TẤT CẢ
sourcepath ..\group

- Source:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
source source-file-list

Ví dụ:
MÃ: CHỌN TẤT CẢ
source HelloWorld_Main.cpp

- UserInclude:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
userinclude directory-list

Ví dụ:
MÃ: CHỌN TẤT CẢ
userinclude ..\inc

- SystemInclude:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
systeminclude directory-list

Ví dụ:
MÃ: CHỌN TẤT CẢ
systeminclude \epoc32\include

- Resource:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
resource resource-file-list

Khai báo tên nên đầy đủ phần mở rộng.
Ví dụ:
MÃ: CHỌN TẤT CẢ
resource HelloWorld.rss

- Library:
Mẫu khai báo:
MÃ: CHỌN TẤT CẢ
library filename-list

Ví dụ:
MÃ: CHỌN TẤT CẢ
library euser.lib apparc.lib cone.lib eikcore.lib


=> Tệp HelloWorld.mmp hoàn chỉnh:
MÃ: CHỌN TẤT CẢ
TARGET HelloWorld.app
TARGETTYPE app
UID 0x100039CE 0x10004299
TARGETPATH \system\apps\HelloWorld
SOURCEPATH .
SOURCE HelloWorld_Main.cpp
SOURCE HelloWorld_Application.cpp
SOURCE HelloWorld_Document.cpp
SOURCE HelloWorld_AppUi.cpp
SOURCE HelloWorld_AppView.cpp
USERINCLUDE .
SYSTEMINCLUDE \epoc32\include
RESOURCE HelloWorld.rss
LIBRARY euser.lib apparc.lib cone.lib eikcore.lib
AIF helloworld.aif \helloworld\aif\ helloaif.rss c8 hello.bmp hellom.bmp


* File mô tả thành phần bld.inf
File này luôn luôn có tên là bld.inf. Nó liệt kê danh sách các file project (thường chỉ 1), file xuất, các nền hệ thống và các file xuất với phần kiểm tra. Nó được công cụ bldmake thực thi để tạo ra file bó abld.batvà các file thực thi khác. Thông thường chỉ có khai báo prj_mmpfiles cho các file project được sử dụng.
Ví dụ: Với project HelloWorld trên, file bld.inf có cấu trúc như sau:
MÃ: CHỌN TẤT CẢ
// Project files
prj_mmpfiles
HelloWorld.mmp

Chú ý:
- Mỗi câu khai báo xuất hiện trên một hàng riêng
- Sử dụng cách ghi chú của C++ cho phần ghi chú(// hoặc /* */)
- Các file nên khai báo đầy đủ phần mở rộng.
- Dấu \ được sử dụng để xác định sự liên tục dòng (dòng dưới cũng thuộc câu lệnh với dòng trên, do dài được cắt xuống), do đó khi khai báo đường dẫn, dấu \ sau cùng phải bỏ đi. Ví dụ nên viết SYSTEMINCLUDE \epoc32\include chứ không phải là SYSTEMINCLUDE \epoc32\include\.