Указатель - Можно ли динамически определить структуру в C

указатель - Можно ли динамически определить структуру в C

указатель на массив структур си (5)

Я уверен, что это станет действительно очевидным вопросом, и именно поэтому я не нашел много информации об этом. Тем не менее, я думал, что стоит спросить :)

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

Однако можно ли динамически определять структуру. Может ли клиентское и серверное приложение согласовывать формат потока данных, а затем использовать это определение как структуру?

Если нет, есть ли лучший способ сделать это?

Вы не можете определить структуру исходного уровня, но вы можете сделать то же самое, настроив структуру данных для хранения имени / тега и смещения для каждого поля данных, которые хотите связываться, а затем сохранить / прочитать данные на правые смещения в соответствии с этим. Убедитесь, что вы привязываете все типы к границе, кратной sizeof(type) для переносимости. Конечно, если вы не уверены, что клиент и сервер будут иметь те же представления данных (сущность и другие соображения) и действительно нуждаются в производительности прямого доступа, я бы вместо этого написал правильные процедуры сериализации и десериализации .

Для динамической структуры ответа нет.

Если вы знаете, какие данные входят в C ++, вы можете использовать перегруженный << в операторе для чтения данных из потока.

В C вы можете преобразовать поток в строку, предполагая, что вы знаете, какая длина данных поступает, и используя такую ​​функцию, как sscanf, вы можете прочитать данные.

Нет, это не в C. Все типы данных должны быть известны во время компиляции. Вот что делает его «настоящим быстрым».

Еще одной теоретической возможностью было бы скомпилировать некоторый код во время выполнения, используя библиотеку компилятора, такую ​​как libtcc.

Хотя она очень привлекательна в теории (она звучит как самомодифицирующееся приложение - ваше приложение должно будет генерировать код C для вашей структуры и вставлять его в шаблон, а затем попросить libtcc скомпилировать его, а затем вызвать некоторые функции, определенные в вашем шаблоне для использования этой структуры), это решение, вероятно, не будет работать отлично на практике. Зачем ? Ну, с 2016 года libtcc (и весь проект tcc) не очень активно развивается и возникают проблемы с такими архитектурами, как x86_64.

Невозможно динамически определить структуру, которая идентична структуре времени компиляции.

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

Все остальное, вы не можете получить доступ к члену somestruct.not_seen_at_compile_time используя . или -> обозначение, если оно не было определено во время компиляции.

В связи с сетевыми коммуникациями существуют другие проблемы, которые необходимо адресовать - в частности, «сущность». То есть данные на проводе, вероятно, будут включать в себя многобайтовые (2, 4, 8) целые числа, и сначала будут отправлены MSB или LSB, но если одна машина является малоконтинентальной (IA-32, IA- 64, x86 / 64), а другой - big-endian (SPARC, PPC, почти ничего, кроме Intel), тогда данные необходимо будет преобразовать. Форматы плавающей точки также могут быть проблематичными. Существует множество стандартов, предназначенных для определения того, как данные будут отправляться по сети - это не тривиально. Некоторые из них специфичны: IP, TCP, UDP; другие являются общими, такими как ASN.1.

Тем не менее, часть «не может выполнять динамические структуры данных» ограничивает ситуацию - вы должны заранее договориться о структуре данных и о том, как они будут интерпретироваться.

Как ты это делаешь?

Возможно, но сложно создать динамические структуры, которые могут содержать информацию, эквивалентную структуре. - Как ты это делаешь? Я хотел бы передать динамически определенные структуры на другой код C (предполагать тот же самый компилятор и другие параметры) без необходимости дублировать процедуры компоновки структуры памяти из компилятора. Я не буду получать доступ к полям этих структур внутри моего процесса (просто инициализируя их один раз), поэтому удобный синтаксис не вызывает беспокойства.

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

dynstruct.c

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

Он также содержит программу main() которая проверяет код. Он вызывает вызов other_function() , который демонстрирует, что структура, определенная в структурах данных, точно соответствует структуре. Данные предполагают 64-битную машину, где double необходимо выровнять по 8-байтовой границе (так что в структуре есть 4-байтовое отверстие); вам придется настроить данные для машины, где double может находиться на 4-байтной границе.

other.c

Этот код ничего не знает о материале описания структуры в dynstruct.c ; он знает о struct simulated модели, имитирующей имитационный код. Он печатает переданные данные и изменяет их.

Образец вывода

Очевидно, что этот код не готов к производству. Это достаточная демонстрация того, что можно сделать. Одна проблема, с которой вам придется иметь дело, - правильно инициализировать данные Structure и Descriptor . Вы не можете вкладывать слишком много утверждений в такой код. Например, я должен действительно иметь assert(d->size == sizeof(double); в get_double_element() . Также было бы разумно включить assert(d->offset % sizeof(double) == 0); что double элемент правильно выровнен или у вас может быть функция validate_structure(const Structure *sp); которая выполнила все эти проверки. Вам понадобится функция void dump_structure(FILE *fp, const char *tag, const Structure *sp); чтобы выгрузить определенную структуру в заданный файл, которому предшествует тег, чтобы помочь в отладке.

Этот код является чистым C; он не компилируется компилятором C ++ как C ++. Недостаточно отливок для компилятора C ++.

📎📎📎📎📎📎📎📎📎📎