Каков идиоматический способ работы с неразмерными массивами в Go? Я работаю над оболочками ETW, и функция TdhGetEventInformation заполняет предоставленный буфер памяти информацией о событии. Метаданные события представлены структурой TRACE_EVENT_INFO, член массива которой объявлен как:
EVENT_PROPERTY_INFO EventPropertyInfoArray[ANYSIZE_ARRAY];
Я вызываю функцию TdhGetEventInformation таким образом, чтобы в предоставленном буфере было достаточно места для заполнения массива свойств события:
var bufferSize uint32 = 4096
buffer := make([]byte, bufferSize)
tdhGetEventInformation.Call(
uintptr(unsafe.Pointer(eventRecord)),
0, 0,
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(unsafe.Pointer(&bufferSize)),
)
Однако, поскольку у меня возникает соблазн смоделировать аналогичную структуру Go с полем EventPropertyInfoArray как
EventPropertyInfoArray [1]EventPropertyInfo
компилятор не может изменить размер массива в соответствии с количеством доступных свойств для каждого события, поэтому я получаю один элемент массива.
Есть ли у вас какие-нибудь умные идеи о том, как справиться с этим крайним случаем?
заранее спасибо





Итак, вам нужен массив переменного размера в Go? Использовать кусочек?
EventPropertyInfoArray [1]EventPropertyInfo
Было бы
EventPropertyInfoArray []EventPropertyInfo
Если у вас есть приблизительное представление о максимуме, который он может удерживать, вы можете создать массив, используя make что-то вроде этого, но это не поможет вам при объявлении структуры:
EventPropertyInfoArray = make([]EventPropertyInfo, len, capacity)
После множества проб и ошибок мне удалось получить правильный срез из резервного массива с помощью стандартной техники превращения массивов в срезы:
properties := (*[1 << 30]EventPropertyInfo)(unsafe.Pointer(&trace.EventPropertyInfoArray[0]))[:trace.PropertyCount:trace.PropertyCount]
К сожалению, я уже пытался преобразовать массив в срез, но все, что я получаю, это срез с причудливой длиной недопустимых записей (попытка проиндексировать срез приводит к неожиданной панике адреса ошибки)