SWIG, C, Python - игнорирование NULL-терминаторов при передаче char * в python - PullRequest
0 голосов
/ 22 мая 2018

Поместите быстро: я хочу отправить полный символ * из модуля C (сборка с SWIG) в функцию обратного вызова Python.

Я уже могу сделать большую часть этого, НО: мой массив символов представляет собой просто двоичные данные и поэтому содержит 0, которые рассматриваются как NULL-терминатор в преобразовании C-> Python.Python получает байты только до первого 0, а не полный массив.

В документации swig конкретно говорится, что обработка char * как двоичных данных возможна с помощью карты типов, но не говорит как.Я играл с cstring.i (% cstring_output_withsize и т. Д.), Но я относительно новичок в SWIG и не в себе.

Как мне сказать SWIG игнорировать терминатор NULL и использовать вместо него значение размерапри переходе на питон?

=========================================================

Если вам нужно больше подробностей:

Для небольшого фона я пишу очень простой сетевой пакетпротокол форматирования / передачи для радиочастотной сети 802.15.4.В сети несколько архитектур, языков и трансиверов, поэтому я пишу в своей библиотеке так, чтобы в ней была установлена ​​настраиваемая настраиваемая функция обратного вызова, позволяющая писать небольшую оболочку на каждой платформе, которая передает буфер байтов трансиверу, использующему этот основной язык.

Ниже приведены ключевые части кода.

//defined in Packets.h
void (*send_callback_ptr)(char * payload, uint8_t payload_length, uint16_t destination,  uint16_t sequence_no);

//a function to set the callback
void send_callback_set(void (*f)(char * payload_buffer, uint8_t payload_length, uint16_t destination,  uint16_t sequence_no))
{
    send_callback_ptr = f;
}


uint8_t send(uint16_t target, enum PACKET_TYPE type, void * packet_object) {
    char * payload_buffer = malloc(128); //max buffer size is 128
    uint8_t payload_length = 12;

    pack(target, type, packet_object, payload_buffer);

    uint16_t destination = target;
    uint16_t sequence_no = GLOBAL.hash++;

    send_callback_ptr(payload, payload_length, destination, sequence_no);
};

Вверху находится функция обратного вызова и функция обратного вызова.«send» принимает цель, тип пакета и объект пакета (void *, поэтому python может передать ему указатель на PyObject).Затем он упаковывает все данные в char * payload_buffer с помощью 'pack ()' (pack просто использует набор правил для упаковки объекта пакета в готовый к отправке байтовый массив).

def py_callback(buffer, buffer_length, destination, seq_no):
    print buffer_length
    print "type:", type(buffer)
    print "length:", len(buffer)

    for i in range(len(buffer)):
        print i, '{:02X}'.format(ord(buffer[i]))

MyModule.send_callback_set(py_callback)

Затем Pythonвыглядит так, что получает полезную нагрузку, payload_length и т. д. из вызова send_callback_ptr в конце функции C send ().

В одном примере функция обратного вызова python получает только 3 байта, когда должна получить 13, поскольку4-й байт в массиве равен 0.

...