与I/O操作相关的sys包问题



因为我想访问一些低级API来使用CreateFile函数进行I/O操作系统调用。创建文件(name *uint16…)在这样做的同时,我面临一个问题,即名称参数是*uint16,但它应该是一个数组([]uint16),以便它可以处理UTF-16格式的字符串。我们可以在Microsoft提供的示例中看到->TEXT宏将字符串转换为wchar_t数组,或者我们可以说[]uint16.

提前表示感谢,如果我说错了什么,我很抱歉,因为我在这个领域只是一个蹒跚学步的孩子。

(方案1)func UTF16PtrFromString(s string) (*uint16, error)内置编码器,返回指向UTF-16编码的指针

(方案2) 由于以前我不知道解决方案1,所以我编写了自己的函数来完成确切的工作,因此您可以忽略此解决方案

要将文件名(字符串)传递给sys包,我们必须首先将字符串转换为UTF-16数组,并传递第一个元素的指针

var srcUTf16 [ ]uint16 = utf16.Encode([ ]rune(src+ "x00"))
syscall.CreateFile(&srcUTf16[0],..... )
  1. 编辑:添加解决方案
  2. 编辑:-在解决方案2中添加正确的解决方案和终止NUL。

我真的不关心Go所做的Windows API函数签名,我已经写过了。如果你愿意,你也可以自己写。创建如下文件:

//go:generate mkwinsyscall -output zfile.go file.go
//sys createFile(name string, access int, mode int, sec *windows.SecurityAttributes, disp int, flag int, template int) (hand int, err error) = kernel32.CreateFileW
package main
import "golang.org/x/sys/windows"
func main() {
n, e := createFile(
"file.txt",
windows.GENERIC_READ,
0,
nil,
windows.CREATE_NEW,
windows.FILE_ATTRIBUTE_NORMAL,
0,
)
if e != nil {
panic(e)
}
println(n)
}

然后构建:

go mod init file
go generate
go mod tidy
go build

我知道结果有效,因为它第一次返回有效句柄,第二次返回无效句柄(当然也因为创建了一个文件):

PS C:> .file.exe
336
PS C:> .file.exe
-1

如果你愿意,你可以编辑我上面的签名行,以满足你的需要。

最新更新