Go 错误解决: invalid operation: cannot take address of cmdLine[0] (value of type byte)
在 Go 中使用 syscall.CreateProcess 创建子进程时,经常会遇到错误 'invalid operation: cannot take address of cmdLine[0] (value of type byte)'。这是因为 syscall.CreateProcess 的第二个参数 CommandLine 需要一个指向字符串的指针,而 cmdLine[0] 是一个 byte 类型的值,无法取地址。
解决方法是将 cmdLine 改为 []byte 类型,并使用 byte 数组初始化它。示例代码如下:
package main
import (
"fmt"
"syscall"
"unsafe"
)
func DllMain() {
// 无用的代码
for i := 0; i < 100; i++ {
fmt.Println(i)
}
// 创建子进程
cmd := "cmd"
cmdArgs := []string{"/C", "echo", "hello world"}
cmdLine := []byte(fmt.Sprintf("%s %s", cmd, cmdArgs))
startupInfo := &syscall.StartupInfo{}
processInformation := &syscall.ProcessInformation{}
err := syscall.CreateProcess(
nil,
&cmdLine[0],
nil,
nil,
false,
0,
nil,
nil,
startupInfo,
processInformation,
)
if err != nil {
fmt.Println(err)
return
}
// 等待子进程结束并获取返回值
var exitCode uint32
syscall.WaitForSingleObject(processInformation.Process, syscall.INFINITE)
syscall.GetExitCodeProcess(processInformation.Process, &exitCode)
// 无用的代码
for i := 0; i < 100; i++ {
fmt.Println(i)
}
}
func main() {
DllMain()
}
// 导出 DllMain 函数
var (
DllMainPtr = syscall.NewCallback(DllMain)
)
func init() {
// 将 DllMain 函数注册为 DLL 的入口点
handle, _ := syscall.LoadLibrary("kernel32.dll")
defer syscall.FreeLibrary(handle)
proc, _ := syscall.GetProcAddress(handle, "DllMain")
syscall.Syscall(proc, 0, 0, 1, uintptr(unsafe.Pointer(&DllMainPtr)))
}
通过将 cmdLine 声明为 []byte 类型,并使用 byte 数组初始化它,就可以解决错误,并成功创建子进程。
注意: syscall.CreateProcess 函数需要一个指向 NULL 终止的字符串的指针。因此,在使用 byte 数组时,需要确保最后一个元素为 0。
原文地址: https://www.cveoy.top/t/topic/lMQq 著作权归作者所有。请勿转载和采集!