Работа с нестандартными массивами в Go и Windows API - PullRequest
0 голосов
/ 25 февраля 2019

Какой идиоматический способ работы с нестандартными массивами в 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

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

У вас есть какие-нибудь умные идеи о том, как обращаться с этим крайним случаем?

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

После большого количества проб и ошибок мне удалось получить правильный срез из резервного массива с помощью стандартного метода для преобразования массивов в срезы:

 properties := (*[1 << 30]EventPropertyInfo)(unsafe.Pointer(&trace.EventPropertyInfoArray[0]))[:trace.PropertyCount:trace.PropertyCount] 
0 голосов
/ 25 февраля 2019

Итак, вы хотите массив переменного размера в Go?Использовать срез?

EventPropertyInfoArray [1]EventPropertyInfo

Было бы

EventPropertyInfoArray []EventPropertyInfo

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

EventPropertyInfoArray = make([]EventPropertyInfo, len, capacity)
...