Symbian Cpp基础语法要点(2)

Use:
? const TDesC& to pass a descriptor for data that you will read from,
but not attempt to change
? TDes& to pass a descriptor for data that you want to change.
Take this global function called greetEntity() as an example:
void greetEntity(TDes& aGreeting, const TDesC& aEntity){
aGreeting.Append(aEntity);
}

You can’t directly modify an HBufC type; however, you can use the
Des() function to create a TPtr through which you can change the
HBufC, and this can prove extremely convenient. For example:
{
_LIT(KTxtHelloWorld,"Hello World!");
_LIT(KTxtFriends,"Friends!");
HBufC* buffer = HBufC::NewL(256);
*buffer = KTxtHelloWorld;
TPtr temp = buffer->Des();
temp.Replace(6,6,KTxtFriends);
...
}

There is a common mistake that many people tend to make once they
become familiar with the Des() function. When they have an HBufC
that is to be passed to a function that takes a const TDesC& type, they
assume that they first have to create a TPtr using Des() and pass this
into the function. While this works, it is far simpler and much more
efficient to simply dereference the heap descriptor; for example, if you
have a function foo() prototyped as
void foo(const TDesC& aDescriptor);
then the following code will work fine:
HBufC* buffer = HBufC::NewL(256);
...
foo(*buffer);

_LIT(KTxtHelloWorld,"Hello World!");
myFunctionL(KtxtHelloWorld);
void myFunctionL(const TDesC& aBuffer)
{
HBufC* mydata = aBuffer.AllocLC();
// do something with this
}
AllocL() (and the Alloc() and AllocLC() variants) creates an
HBufC that is big enough to contain aBuffer’s data, and then copies
the data fromaBuffer into mydata. AllocL() does three jobs in one:
it works out the length of the source descriptor, it allocates the heap
descriptor, and then it copies the data into the heap descriptor.
A common mistake is to do this explicitly (calling Length() on
aBuffer, then calling NewL() to create the HBufC, and then calling
Copy() on the HBufC), which is wasteful and inefficient.

Symbian OS implements preemptive multitasking so that it can run
multiple applications and servers concurrently. Active objects, however,
are used to implement non-preemptive multitasking within the context
of a single thread.

The function that gets called to handle an event is the active object’s
RunL().

In many systems, the preferred way to multitask is to multithread. In
Symbian OS, the preferred way to multitask is to use active objects.
active Object是基于单线程的非抢占多任务

An active object must implement a DoCancel() function, and must
also call Cancel() in its destructor.

This is the invariable pattern for active object request functions. Assert
that no request is already active (or, in rare cases, cancel it). Then
issue a request, passing your iStatus to some function that will later
generate an event. Then call SetActive() to indicate that the request
has been issued.

A thread can have many active objects. Each active object is associated
with just one object that has request functions – functions that take a
TRequestStatus& parameter. When a program calls an active object’s
request function (SetHello() in the delayed hello example we saw
earlier), the active object passes the request on to the asynchronous service
provider. It passes its own iStatus member as the TRequestStatus&
parameter to the request function and, having called the request function,
it immediately calls SetActive().
The TRequestStatus is a 32-bit object, intended to take a completion
code. Before starting to execute the request function, the asynchronous
service provider sets the value of the TRequestStatus to
KRequestPending, which is defined as 0x80000001.
When the asynchronous service provider finishes processing the
request, it generates an event. This means it signals the requesting thread’s
request semaphore, andalso posts a completion code (such as KErrNone
or any other standard error code – anything except KRequestPending
is permissible) into the TRequestStatus.
The active scheduler is responsible for detecting the occurrence of an
event, so as to associate it with the active object which requested it, and
call RunL() on that active object.
The active scheduler calls User::WaitForAnyRequest() to detect
an event. This function suspends the thread until one or more requests
have completed. The active scheduler then scans through all its active
objects, searching for one which has issued a request (iActive is set)
and for which the request has completed (iStatus is some value other
than KRequestPending). It clears that object’s iActive and calls
its RunL(). When the RunL() has completed, the scheduler issues
User::WaitForAnyRequest() again.
So the scheduler handles precisely one event per User::WaitFor-
AnyRequest(). If more than one event is outstanding, there’s no
problem: the next User::WaitForAnyRequest() will complete
immediately without suspending the thread, and the scheduler will find
the active object associated with the completed event.
If the scheduler can’t find the active object associated with an event,
this indicates a programming error known as a stray signal. The active
scheduler panics the thread.
Given the delicacy of this description, you might expect writing
an active object to be difficult. In fact, as we’ve already seen with
CDelayedHello, it’s not. You simply have to:
? issue request functions to an asynchronous service provider, remembering
to call SetActive() after you have done so
? handle completed requests with RunL()
? be able to cancel requests with DoCancel()
? set an appropriate priority
? handle leaving from the RunL() with RunError().
Indeed, if the active scheduler is signaled more than once before it can
dispatch an active object’s RunL(), it has to decide which active object
to service first. This is the reason for assigning priorities to active objects.
The one with the highest priority value is dispatched first.
The CActive class defines a basic set of priority values, encapsulated
by the TPriority enum, and the application framework defines
an additional set, TActivePriority. Most applications will use CActive::
EPriorityStandard as their standard priority value, but if you
need to use non-zero values for your own active objects, then you’ll need
to look at the enum values so that you can ensure you fit in with them.

Symbian OS Comms Architecture
Each of the key frameworks uses the Symbian OS client/server architecture.
In this architecture, a program running in the background (the server)
offers services to multiple other programs (the clients).

The cell location indicator requires very little space, and when the window is re-sized, any extra space should go to the cell formula indicator on the right. This is achieved by specifying a stretch factor of 1 in the formula label's QStatusBar::addWidget() call. The location indicator has the default stretch factor of 0, meaning that it prefers not to be stretched.

Classes like QTextEdit and QAbstractItemView (the base class of Qt's item view classes) derive from QAbstractScrollArea, so we don't need to wrap them in a QScrollArea to get scroll bars.

The value type T can also be a container, in which case we must remember to separate consecutive angle brackets with spaces; otherwise, the compiler will choke on what it thinks is a >> operator. For example:
QList<QVector<double> > list;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值