Главная » Просмотр файлов » Руководство программиста в Photon

Руководство программиста в Photon (953920), страница 41

Файл №953920 Руководство программиста в Photon (Руководство программиста в Photon) 41 страницаРуководство программиста в Photon (953920) страница 412013-09-22СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 41)

-e Если другой экземпляр приложения уже выполняется, приказать ему закрыться

-f file Если другой экземпляр приложения уже выполняется, приказать ему открыть заданный файл, в противном случае просто открыть файл.

Вот код:

/* Стандартные хеадеры */

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

/* Инструментальные хеадеры */

#include <Ph.h>

#include <Pt.h>

#include <Ap.h>

/* Локальные хеадеры */

#include "abimport.h"

#include "proto.h"

enum MyMsgType {

MY_MSGTYPE_EXIT, MY_MSGTYPE_OPEN_DOC, MY_MSGTYPE_TOFRONT

};

enum MyReplyType {

MY_REPTYPE_SUCCESS, MY_REPTYPE_BADMSG

};

struct MyMsg {

char docname[ PATH_MAX ];

};

struct MyReply {

enum MyReplyType status;

};

/* Обработка сообщений клиента: */

static PtConnectionMsgFunc_t msghandler;

static void const *msghandler(

PtConnectionServer_t *connection, void *data,

unsigned long type, void const *msgptr,

unsigned msglen, unsigned *reply_len

) {

struct MyMsg const *msg = (struct MyMsg const*) msgptr;

struct MyReply reply;

reply.status = MY_REPTYPE_SUCCESS;

switch ( type ) {

case MY_MSGTYPE_EXIT :

PtConnectionReply( connection, sizeof(reply), &reply );

PtExit( EXIT_SUCCESS );

break;

case MY_MSGTYPE_OPEN_DOC :

reply.status = OpenNewDocument( msg->docname );

break;

case MY_MSGTYPE_TOFRONT : break;

default : reply.status = MY_REPTYPE_BADMSG;

} // switch(type)

PtWindowToFront( ABW_base );

*reply_len = sizeof(reply);

return &reply;

} // Функции msghandler()

/* Установка нового коннектора: */

static PtConnectorCallbackFunc_t connector_callback;

static void connector_callback(

PtConnector_t *connector,

PtConnectionServer_t *connection,

void *data ) {

static const PtConnectionMsgHandler_t

handlers = { 0, msghandler };

if ( PtConnectionAddMsgHandlers( connection, &handlers, 1 ) != 0 ) {

fputs( "Unable to set up connection handler\n", stderr );

PtConnectionServerDestroy( connection );

} } // Функции connector_callback()

/* Строка Опций приложения */

const char ApOptions[] = AB_OPTIONS "ef:"; /* Добавление Ваших опций в "" */

/* Функция инициализации приложения */

int init( int argc, char *argv[] ) {

struct MyMsg msg;

int opt;

long msgtype = MY_MSGTYPE_TOFRONT;

const char *document = NULL;

static const char name[] = "me@myself.com/ConnectionExample";

while ( ( opt = getopt( argc, argv, ApOptions ) ) != -1 )

switch ( opt ) {

case '?' : PtExit( EXIT_FAILURE );

case 'e' : msgtype = MY_MSGTYPE_EXIT; break;

case 'f' : document = optarg;

}

if ( document )

if ( msgtype == MY_MSGTYPE_EXIT ) {

fputs("Вы не можете задать одновременно опции -e и -f\n", stderr );

PtExit( EXIT_FAILURE );

}

else {

msgtype = MY_MSGTYPE_OPEN_DOC;

strncpy( msg.docname, document, sizeof(msg.docname)-1 );

}

while ( PtConnectorCreate( name, connector_callback, 0 ) = = NULL ) {

/* Если это вернуло неудачу, должно быть другой экземпляр приложения уже запущен */

PtConnectionClient_t *clnt;

if ( ( clnt = PtConnectionFindName( name, 0, 0 ) ) != 0 ) {

struct MyReply reply;

int result = PtConnectionSend( clnt, msgtype, &msg, &reply, sizeof(msg), sizeof(reply) );

PtConnectionClientDestroy( clnt );

if (result = = 0) PtExit( reply.status );

}}

/* Поскольку PtConnectorCreate() выполнен успешно,

выполняется только один экземпляр приложения */

if ( msgtype == MY_MSGTYPE_EXIT ) {

fputs( "Не могу приказать ему завершиться; он и так не выполняется\n", stderr );

PtExit( EXIT_FAILURE );

}

if ( document ) OpenNewDocument( document );

return Pt_CONTINUE;

}

Отсылка QNX-сообщений

Приложение Photon'а может использовать MsgSend(), чтобы передавать сообщения другому процессу, но другому процессу надо сразу же выполнять функцию MsgReply(), поскольку события Photon'а не обрабатываются, пока приложение блокировано. ("Расторопность" не является проблемой, если Ваше приложение имеет множество потоков, работающих с событиями, и Вы вызываете функцию PtLeave() перед и функцию PtEnter() после вызова функции MsgSend() ).

Вот в качестве примера ответная реакция, которая извлекает строку из текстового виджета, отсылает её другому процессу, и отображает ответ в том же текстовом виджете:

/* Ответная реакция, отсылающая сообщение другому процессу */

/* Стандартные хеадеры */

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <sys/neutrino.h> /* Требуется для MsgSend() */

/* Инструментальные хеадеры */

#include <Ph.h>

#include <Pt.h>

#include <Ap.h>

/* Локальные хеадеры */

#include "globals.h"

#include "abimport.h"

#include "proto.h"

extern int coid;

int send_msg_to_b( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo ) {

char *a_message;

/* предотвращает предупреждения (варнинги) об отсутствии ссылок */

widget = widget, apinfo = apinfo, cbinfo = cbinfo;

/* Получает строку из текстового виджета */

PtGetResource (ABW_msg_text, Pt_ARG_TEXT_STRING, 0, 0);

/* Отсылает строку другому процессу */

a_message = (char *)args[0].value;

if ( MsgSend (coid, a_message, msg_size, rcv_msg, msg_size) == -1) {

perror ("Отсылка не удалась ");

PtExit (-1);

}

/* Помните, что UI (пользовательский интерфейс) "висит",

пока другой процесс не ответит! */

/* Отображение ответа в том же текстовом виджете */

PtSetResource (ABW_msg_text, Pt_ARG_TEXT_STRING, rcv_msg, 0);

return( Pt_CONTINUE );

}

Для получения подробной информации см. "Руководство по системной архитектуре QNX 6".

Приём QNX-сообщений

Чтобы получать события от Photon, библиотечные функции виджета выполняют безоговорочный MsgReceive(), помещающий принятое событие в буфер событий контекста приложения. Если сообщение не является событием Photon'а, оно отвергается, пока Вы не зарегестрировали в Вашем приложении некую процедуру обработки ввода (или обработчик ввода).

 Вы можете создать Ваш собственный канал и вызвать функцию MsgReceive() в нём, но помните, что Ваше приложение и его интерфейс будут блокированы до тех пор, пока процесс не пришлёт сообщение. Лучше использовать обработчик ввода, как это описано в настоящем разделе.

Обработчик ввода отвечает за обработку сообщений, принятых приложением от конкретного процесса. Когда Вы регистрируете обработчик библиотечными функциями виджета, Вы идентифицируете rcvid, с которым соединён обработчик ввода.

Вы можете определить в Вашем приложении более одного обработчика ввода для rcvid, но только последний зарегестрированный будет вызываться библиотекой виджета, когда от процесса будет получено сообщение.

Вы можете зарегистрировать неопределённый обработчик ввода, определив в качестве rcvid нулевое значение. Такой обработчик вызывается, когда приложение получает:

  • любое не-Photon'овское сообщение, которое не имеет обработчика ввода, конкретно связанного с rcvid клиента.

  • пользовательский импульс (т.е. импульс с неотрицательным кодом).

Добавление обработчика ввода

Чтобы зарегистрировать обработчик ввода, вызовите при инициализации приложения функцию PtAppAddInput(). Её синтаксис дан ниже; более подробно информацию см. в "Справочнике библиотечных функций Photon'а".

PtInputId_t *PtAppAddInput(

PtAppContext_t app_context,

pid_t pid,

PtInputCallbackProc_t input_func,

void *data );

Аргументами функции являются:

app_context

Адрес контекста приложения, структуры типа PtAppContext_t, управляющей всеми данными, связанными с приложением. Обычно Вы в этом аргументе передаёте NULL, так что используется контекст по умолчанию

pid

Либо идентификатор процесса, с чьими сообщениями имеет дело этот обработчик, либо 0, если обработчик обрабатывает сообщения от всех процессов

input_func

Ваш обработчик ввода, имеющий тип PtInputCallbackProc_t. Подробности см. в "Справочнике библиотечных функций Photon'а"

data

Дополнительные данные, передаваемые обработчику ввода

Функция PtAppAddInput() возвращает указатель на идентификатор обработчика ввода, который понадобится Вам, если Вы захотите потом удалить этот обработчик ввода.

Прототип обработчика ввода имеет следующий вид:

int input_proc(void *data,

int rcvid,

void *msg,

size_t msglen);

аргументами его являются:

data

Указатель на какие-либо дополнительные данные, которые Вы хотите передать обработчику ввода.

rcvid

Идентификатор отправителя – процесса, пославшего сообщение.

msg

Указатель на отосланное сообщение.

msglen

Размер буфера сообщения. Если действительное сообщение больше буфера, загрузите оставшуюся часть сообщения вызовом MsgRead().

Вы можете также объявить обработчик ввода типа PtInputCallbackProcF_t, получив дополнительную выгоду от применения прототипа, проверяемого компилятором.

 Если Ваш обработчик ввода изменяет изображение, он должен вызвать функцию PtFlash(), чтобы изображение наверняка обновилось.

Обработчик ввода должен возвращать одно из следующих значений:

Pt_CONTINUE

Обработчик ввода не опознал сообщение. Если имеются другие обработчики ввода, прикреплённые к тому же идентификатору процесса, вызываются они. Если отсутствуют обработчики ввода, прикреплённые к этому конкретному идентификатору процесса, или если все обработчики ввода, прикреплённые к этому конкретному идентификатору процесса, вернули Pt_CONTINUE, библиотека ищет обработчики ввода, прикреплённые к нулевому идентификатору отправителя. Если все обработчики ввода вернули Pt_CONTINUE, библиотека отвечает сообщением с кодом ENOSYS.

Pt_END

Сообщение было опознано и обработано и обработчик ввода должен быть удалён из списка. Никакие другие обработчики ввода для данного сообщения не вызывались.

Pt_HALT

Сообщение было опознано и обработано, но обработчик ввода должен оставаться в списке. Никакие другие обработчики ввода для данного сообщения не вызывались.

Функции name_attach и PtAppAddInput()

Если возможно, Вам следует использовать для установки связи с другими процессами Photon'овскую коннекцию вместо функции name_attach(). Вы не можете использовать Photon'овскую коннекцию в следующих случаях:

  • Клиент, подключающийся к связи, не является приложением Photon'а.

  • Клиент, подключающийся к связи, принадлежит другой сессии Photon'а.

Это касается равным образом как случая, когда Вы запускаете несколько сессий Photon'а на одной машине, так и случая, когда Ваша сессия Photon'а состоит из приложений, исполняющих на нескольких машинах и два соединяющихся процесса оказываются на различных машинах.

PtAppAddInput() и name_attach() обе пытаются создать канал с установками _NTO_CHF_COID_DISCONNECT и _NTO_CHF_DISCONNECT (см. "Справочник библиотечных функций QNX 6"). Если Ваше приложение вызывает обе функции, Вам надо позволить Photon'у использовать тот же канал, что и использует функция name_attach(), вызвав прежде всего функцию PhChannelAtach() таким образом:

PhChannelAtach(chid, -1, NULL);

перед вызовами функций name_attach() или PhAppAddInput(). Если Вы хотите создать отдельный канал для Photon'а, нет разницы, создаёте ли Вы его и передаёте его функции PhChannelAtach() до или после вызова name_attach(). Но имейте в виду, что поскольку определённые механизмы библиотеки Photon'а предполагают, что канал Photon'а имеет два установленных флага DISCONNECT, они могут неправильно работать, если это не так. Одним из таких механизмов является определение нарушенной связи (см. функции PtConnectionClientSetError() и PtConnectionServerSetError()) и всё, что зависит от этого механизма.

Удаление обработчика ввода

Чтобы удалить обработчик ввода:

  • Получите от него код возврата Pt_END

или

  • Вызовите функцию PtAppRemoveInput(), передав её в качестве аргумента идентификатор, возвращённый функцией PtAppAddInput().

Размер буфера сообщений

Как описано выше, аргументы Вашей функции ввода включают:

msg Указатель на буфер событий, использованный для получения сообщений.

msglen Размер буфера.

Этот буфер может оказаться недостаточно велик, чтобы вместить целиком всё сообщение. Одним из способов обработки этого – выделять первые несколько байт сообщения под указание типа сообщения и отсюда определять, насколько большим оно может быть. Как только Вы узнаете размер сообщения, Вы сможете:

  • Перечитать сообщение целиком, вызвав функцию MsgReadv()

или

  • Скопировать часть, которую Вы уже получили, в новый буфер. Получить остаток сообщения, вызвав MsgReadv(). Добавить остаток сообщения к первой части.

Альтернативным способом является установка размера буфера событий таким, чтобы он мог вместить самое большое сообщение, которое получит Ваше приложение (если Вы это знаете). Это может быть выполнено функцией PtResizeEventMsg(). Обычно Вы должны выполнить этот вызов до того, как предполагаете получить какие-либо сообщения.

Характеристики

Тип файла
Документ
Размер
7,62 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6418
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее