|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-CF6014E9-FB59-4715-B245-5826090DDF28" xml:lang="en"><title>Symbian |
|
13 Platform vs UNIX</title><shortdesc/><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <section id="GUID-977EFA64-8D61-44CA-9A89-64D8DB0F771E"> <title>Hello World</title><p>Assuming |
|
15 that the user is new to the UNIX environment, writing a simple program that |
|
16 displays a string on a console does not take more than a day’s effort. Its |
|
17 simply 4-5 lines of code as shown below: </p><codeblock xml:space="preserve">#include <stdio.h> |
|
18 int main(int argc, char** argv) |
|
19 { |
|
20 printf(“Hello world\n”); |
|
21 return 0; |
|
22 }</codeblock><p>The code contains a <codeph>main()</codeph> , one <codeph>printf</codeph> statement, |
|
23 and one <codeph>#include< ></codeph>. By convention UNIX applications will |
|
24 map descriptor 0 with standard input (<codeph>STDIN</codeph>), descriptor |
|
25 1 with standard output (<codeph>STDOUT</codeph>), and descriptor 2 with standard |
|
26 error (<codeph>STDERROR</codeph>) of the process. So, there is no need to |
|
27 create/open standard input/output/error for a process before using them. Notice |
|
28 also that, <codeph>main()</codeph> takes two arguments. These arguments will |
|
29 be read from the command prompt before invoking <codeph>main()</codeph> and |
|
30 will be passed to main. These arguments are not mandatory; they can be ignored. |
|
31 No additional work is needed for having these arguments. </p><p>If the user |
|
32 attempts to display a string on a console using Symbian platform, a lot of |
|
33 effort goes into collecting the materials, and for coding. The first time |
|
34 the developer may find the code a little complex to understand.</p><codeblock xml:space="preserve">#include <e32std.h> |
|
35 #include <e32cons.h> |
|
36 int HelloWorldL() |
|
37 { |
|
38 CConsoleBase* console = Console::NewL(_L("Hello World"), TSize( KConsFullScreen, KConsFullScreen)); |
|
39 console->Printf(_L(“Hello World\n”)); |
|
40 delete console; |
|
41 return 0; |
|
42 } |
|
43 |
|
44 TInt E32Main() |
|
45 { |
|
46 __UHEAP_MARK; |
|
47 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
48 TInt retVal = KErrNone; |
|
49 if (cleanup) |
|
50 { |
|
51 TRAP(retVal, HelloWorldL()); |
|
52 __ASSERT_ALWAYS(!retVal, User::Panic(_L("Hello-World PANIC"), retVal)); |
|
53 //Destroy cleanup stack |
|
54 delete cleanup; |
|
55 } |
|
56 __UHEAP_MARKEND; |
|
57 return retVal; |
|
58 } |
|
59 </codeblock><p>The code above has some header inclusions, two functions, and |
|
60 some complicated codes. In Symbian platform, the entry function for an EXE |
|
61 is <codeph>E32Main</codeph> (not main as in UNIX). The following actions are |
|
62 done to print a message on a console: </p><ol> |
|
63 <li id="GUID-11FE80AB-BD78-4A53-88D4-90E9CE3158EF"><p>Mark the heap using <codeph>__UHEAP_MARK</codeph> (not |
|
64 mandatory).</p></li> |
|
65 <li id="GUID-5292A0E8-5158-4A3B-89DC-095D570AEDA7"><p>Create the cleanup stack. |
|
66 Have a top-level TRAP for the function <codeph>HelloWorldL()</codeph> function.</p></li> |
|
67 <li id="GUID-E47E4F4F-EC51-4D7F-8254-0329A6DC1689"><p>In the <codeph>HelloWorldL()</codeph> function, |
|
68 create a console object.</p></li> |
|
69 <li id="GUID-8CAA7ADA-3EE1-470E-A376-DAD345066BF2"><p>Do print on the created |
|
70 console object.</p></li> |
|
71 <li id="GUID-8ABFB71E-A89A-4D02-9CBC-50FACC853805"><p>Delete the console.</p></li> |
|
72 <li id="GUID-4FDC0B1D-0DAB-42AF-9E54-A53DBDD47327"><p>Delete the cleanup stack.</p></li> |
|
73 <li id="GUID-187B70A6-D15E-4197-A742-372F6E385FEC"><p>Unmark the heap (not |
|
74 mandatory if the heap is not marked). </p></li> |
|
75 </ol><p>In Symbian platform, a console is not created by default; it has to |
|
76 be created explicitly. Symbian platform does not give a rich set of APIs needed |
|
77 to perform I/O operations on a console. The I/O operations that can be performed |
|
78 on a console in Symbian platform are limited to:</p><ul> |
|
79 <li><p>printing strings and reading one character at a time</p></li> |
|
80 <li><p>getting cursor position </p></li> |
|
81 </ul><p>In case the user is interested in command line arguments, it takes |
|
82 some more additional work. The user must read explicitly from the command |
|
83 prompt by using the APIs provided by Symbian platform.</p> </section> |
|
84 <section id="GUID-3FC28B5E-4D46-4E33-90E8-AB9A1FBC038E"><title>File I/O</title><p>This |
|
85 section compares the ease of programming in the P.I.P.S. environment against |
|
86 programming on Symbian platform.</p><codeblock xml:space="preserve">/* File I/O in UNIX environment */ |
|
87 FILE* fp = fopen(“file.txt”, w); |
|
88 if (fp) { |
|
89 fprintf(fp, “Write some data”); |
|
90 fclose(); |
|
91 } |
|
92 </codeblock><codeblock xml:space="preserve">//File I/O in Symbian platform |
|
93 RFs fSession; |
|
94 User::LeaveIfError(fSession.Connect()); |
|
95 RFile file; |
|
96 ret = file.Open(fSession, _L(“file.txt”), EFileWrite); |
|
97 if (ret) |
|
98 { |
|
99 ret = file.Create(fSession, _L(“file.txt”), EFileWrite); |
|
100 } |
|
101 if (!ret) |
|
102 { |
|
103 file.Write(_L8(“Write some data”)); |
|
104 } |
|
105 file.Close(); |
|
106 fSession.Close(); |
|
107 </codeblock><p>The example above shows the complexity of the code in Symbian |
|
108 platform for doing simple file I/O. In addition to coding complexity, the |
|
109 user must include and link with:</p><ul> |
|
110 <li><p><filepath>efsrv.lib</filepath> for any file-related operation</p></li> |
|
111 <li><p><filepath>esock.lib</filepath> for network-related operation</p></li> |
|
112 <li><p><filepath>commdb.lib</filepath> for selecting IAPs </p></li> |
|
113 </ul><p>Since most of the resources under Symbian platform are accessed through |
|
114 client/server IPC, the user must connect with the corresponding server before |
|
115 doing any operation and close the session on completion of the operation. |
|
116 For example: <ul> |
|
117 <li><p>connect with the file server before file operations</p></li> |
|
118 <li><p>connect with the socket server for socket-related operation</p></li> |
|
119 <li><p>connect to the communication server before serial communication operation</p></li> |
|
120 </ul></p><p>P.I.P.S. eliminates all these operations. P.I.P.S. allows the |
|
121 user to code, as if it were done for the UNIX or Linux environment and lets |
|
122 the user link the application with P.I.P.S.</p></section> |
|
123 <section id="GUID-AFAE7FDA-8829-4FF7-991F-D65EBAA652F2"><title>Thread creation</title><p>This |
|
124 section deals with thread creation in the UNIX and Symbian platform environments.</p><codeblock xml:space="preserve">/* Thread creation in UNIX environment*/ |
|
125 void* ThreadEntryPoint( void* aParam ); |
|
126 int exitReason = 0; |
|
127 int retVal = 0; |
|
128 pthread_t threadID = 0; |
|
129 pthread_attr_t threadAttr; |
|
130 pthread_attr_init(&threadAttr); |
|
131 retVal = pthread_create(&threadID, &threadAttr, ThreadEntryPoint, (void*)NULL ); |
|
132 if(retVal == 0) { |
|
133 retVal = pthread_join(threadID1, (void**)&exitReason); |
|
134 } |
|
135 </codeblock><codeblock xml:space="preserve">// Thread creation in Symbian Platform |
|
136 TInt ThreadEntryPoint( TAny* aData ); |
|
137 … |
|
138 RThread thread; |
|
139 thread.Create(_L("MY-THREAD"), ThreadEntryPoint, 4096, NULL, NULL); |
|
140 TRequestStatus stat; |
|
141 thread.Logon(stat); |
|
142 //Start executing the thread. |
|
143 thread.Resume(); |
|
144 //Wait for the thread to die. |
|
145 User::WaitForRequest(stat); |
|
146 exitReason = thread.ExitReason(); |
|
147 thread.Close(); |
|
148 </codeblock><p>In addition the difference in the code for creating threads |
|
149 using <codeph>pthread_create</codeph> and <xref href="GUID-B0E661BC-4058-3256-B9C3-5A4FD52F6DE5.dita#GUID-B0E661BC-4058-3256-B9C3-5A4FD52F6DE5/GUID-6C840907-C3F7-34B7-97DB-CEDBA68EA277"><apiname>RThread::Create()</apiname></xref>, |
|
150 a thread created using <xref href="GUID-B0E661BC-4058-3256-B9C3-5A4FD52F6DE5.dita#GUID-B0E661BC-4058-3256-B9C3-5A4FD52F6DE5/GUID-6C840907-C3F7-34B7-97DB-CEDBA68EA277"><apiname>RThread::Create()</apiname></xref> also expects the <codeph>ThreadEntryPoint()</codeph> function |
|
151 to create its own vcleanup stack and a top-level TRAP, if required. Else, |
|
152 the thread may crash or panic. But this does not have to be done for a thread |
|
153 created using <codeph>pthread_create. pthread_create</codeph> does that for |
|
154 the developer.</p></section> |
|
155 </conbody></concept> |