Я пишу приложение, которое взаимодействует с Windows API из службы Windows.Вызов EnumServicesStatusEx в Go, выделение памяти?
После загрузки справки от @chowey here, я как бы повесил вещи и основал базовую библиотеку, которую я надел GitHub here.
Теперь я перешел к «Службам», с требованием перечислить все службы Windows на машине, запустить, остановить, перезапустить их. Запуск/останов/перезапуск выглядят довольно прямолинейно, когда у вас есть служебный дескриптор, с которым я работаю, но я боюсь получить список установленных сервисов.
EnumServicesStatusEx в Advapi32.dll - это функция, которую мне нужно вызвать, но для этого требуется указатель на предварительно выделенную память для массива из ENUM_SERVICE_STATUS_PROCESS structs.
Вы можете вызвать функцию с помощью нулевого указателя, и она вернет требуемый размер выделения памяти, но я не верю, что есть способ напрямую выделить память в Go.
Сначала я думал, что могу получить требование распределения памяти, делить его на SizeOf на структуру, используя небезопасный пакет, создать срез, содержащий это число элементов, а затем передать указатель на первый элемент функции, но он говорит, что память должна включать в себя пространство для строковых данных, чего не было бы.
Кто-нибудь знает, как это может быть выполнено, пожалуйста? :).
От EnumServicesStatusEx DOCO: 'lpServices [из факультативные] Указатель на буфер, который получает информацию о состоянии. ... Чтобы определить требуемый размер, укажите NULL для этого параметра и 0 для параметра cbBufSize. Функция завершится с ошибкой, и GetLastError вернет ERROR_MORE_DATA. Параметр pcbBytesNeeded получит требуемый размер. '. Как только вы узнаете, насколько велик ваш буфер, снова вызовите EnumServicesStatusEx с буфером такого размера. – alex
Здравствуйте, @alex, как описано выше, я не знаю, как сделать Go напрямую распределять память. Вы должны предоставить ему структуру данных, чтобы сделать ее выделенной памятью, а затем разоблачить эту память через небезопасный пакет. – iamacarpet
вы сами сказали: 'создайте срез, содержащий это число элементов, а затем передайте указатель на первый элемент функции'. From EnumServicesStatusEx doco: 'cbBufSize [in] Размер буфера, на который указывает параметр lpServices, в байтах. Поэтому вы можете создать массив байтов cbBufSize и передать адрес первого элемента этого массива в EnumServicesStatusEx. Например, https://github.com/golang/go/blob/master/src/internal/syscall/windows/registry/value.go#L71. В отличие от примера, вы должны начать с передачи lpServices = nil в соответствии с EnumServicesStatusEx doco. – alex