Использование функций с переменным числом аргументов.
В CZMQ появилось много методов с переменным число аргументов. В описании таких методов присутствует модификатор
function zsock_connect(p_self: p_zsock_t; format: PChar): Integer; varargs;
cdecl; external cZMQ_DllName;
или
function zsock_send(self: Pointer; picture: PChar): Integer; varargs; cdecl; external cZMQ_DllName;
Как ими пользоваться?
В первом случае (zsock_connect) дополнительные параметры являют аргументами Си-шного классического format-а:
zsock_connect(fSocket, 'tcp://%s:%d', pChar('localhost'), 5555);
В данном случае %s будет заменен null-terminated строкой 'localhost', %d - целым числом 5555. Если есть сомнения в типе данных - используем явное приведение типа.
Во втором случае (zsock_send) дополнительные параметры являют аргументами format-а от CZMQ, маска формата задается в аргументе picture. Picture - это строка, которая определяет тип каждого кадра сообщения и может содержать любые из следующих символов, каждый из которых соответствует нулю, одному, или двум дополнительным аргументам:
i = integer
s = PChar (указатель на null - terminated строку)
b = pByte, size_t (2 аргумента: указатель на массив байтов и длина массива)
c = p_zchunk_t
f = p_zframe_t
h = p_zhash_t
m = p_zmsg_t (будут отправлены все кадры zmsg)
p = Pointer (отправляет значение указателя, имеет смысл только для протокола inproc)
z = отправляет пустой кадр-разделитель (0 аргументов)
Замечание: s, b, c и f кодируются одинаковым способом; интерпретация данных возложена на клиента.
Пример:
var fB : Byte; ... begin fB := 127; zsock_send(fSocket, 'izsb', Integer(3), PChar('Hello!'), @fB, Integer(1))
Будут отправлены кадры:
i - целое, значение 3.
z - пустой кадр-разделитель.
s - строка 'Hello.
b - один байт, значение 127.
Метод zsock_send не меняет пересылаемые данные (кроме случая с m). Для метода zsock_recv:
...
С методом
function zsock_recv(self: Pointer; picture: PChar): Integer; varargs;
cdecl; external cZMQ_DllName;
дело обстоит несколько иначе:
i = pInteger (размещает принятое целое по указанному адресу)
s = ^pChar (принимает/создает строку, адрес которой помещает по указанному адресу)
b = ^pByte, ^size_t (2 аргумента) (принимает массив данных, адрес помещает по указанному адресу, длину помещает в целое по указанному адресу)
c = ^p_zchunk_t (создает чанк, адрес помещает по указанному адресу)
f = ^p_zframe_t (создает zframe, адрес помещает по указанному адресу)
p = ^Pointer (размещает принятый указаетль по указанному адресу)
h = ^p_zhash_t(создает zhash, адрес помещает по указанному адресу)
m = ^p_zmsg_t (создает zmsg со всеми кадрами, адрес помещает по указанному адресу)
z = пусто, "проглатывает" пустой кадр (0 аргументов)
Пример:
var fB : pByte;
fCnt : Integer;
fInt : Integer;
fStr : PChar;
... begin zsock_recv(fSocket, 'izsb', @fInt,@ fStr, @fB, @fCnt)
Будут приняты кадры:
i - целое, значение будет помещено в fInt
z - пустой кадр-разделитель.
s - строка, адрес будет помешен в fStr.
b - массив байт, адрес будет помещен в fB, длина массива - в fCnt.
Таким образом, аргументами являются указатели, по которым размещаются принятые данные. Если значение указателя - nil, соответствующий кадр будет пропущен (не размещен в памяти).
После использования созданных объектов следует освободить память с помощью zstr_free():
zstr_free(fStr);
zstr_free(PChar(fB));
Во всех случаях следует внимательно читать комментарии к конкретному методу и помнить, что аргументы в языке C всегда передаются только по значению.
Замечание.
Дополнительные (те, которые "varargs") параметры методов:
zsock_send(self: Pointer; picture: PChar): Integer; varargs; cdecl; external cZMQ_DllName;
и
zsock_recv(self: Pointer; picture: PChar): Integer; varargs; cdecl; external cZMQ_DllName;
передаются и принимаются отдельными кадрами.
Если в picture присутствует опция "m", то будет передано (принято) все сообщение из структуру p_zmsg_t. Следует учесть, что для некоторых типов сокетов при передаче автоматически вставляются дополнительные кадры, а при приеме - удаляются. Например, в сообщение, формируемое сокетами ZMQ_DEALER, в начало сообщения добавляется дополнительный кадр (идентификация). Это следует учитывать, если принять такое сообщение сокетом ZMQ_ROUTER. В то же время такой (первый) кадр будет отброшен при приеме сообщение сокетом ZMQ_DEALER.
Комментариев нет :
Отправить комментарий