在 Go 中将字符串传递给 Syscall 的参数 [英] Pass String to argument of Syscall in Go
问题描述
我想使用编译成 DLL 的 C 函数.这是我想使用的 C 函数:
int setProxy(const proxy_config* p_proxy);
它需要一个指向 C 结构的常量指针,定义如下:
typedef 结构体{字符 *host_address;国际端口;字符 *用户名;字符 *密码;代理配置;
为此,我将这个 C_structure 转换成 Go 的等价物,如下所示:
type proxy_configuration struct {主机地址 *uint16端口号用户名 *uint16密码 *uint16}
要转换字符串,我使用以下函数:
func StringToCString(s string) (*uint16, error) {对于我:= 0;我<镜片);我++ {如果 s[i] == 0 {return nil, errors.New("字符串有问题:"+s)}}p := utf16.Encode([]rune(s + "\x00"))返回 &p[0], nil}
然后我称之为:
import (系统调用"不安全")func SetProxy(host_address string, port int, username string, password string) 错误{[...从 Go 字符串到 Struct 的转换代码...]var nargs uintptr = 1ret, _, callErr := syscall.Syscall(uintptr(setProxy),nargs,uintptr(unsafe.Pointer(&proxy)),0,0,)}
其中 setProxy
是 syscall.GetProcAddress(DLL,"setProxy")
问题是,当我查看 DLL 生成的日志时,所有 *uint16
只包含一个字符而不是整个字符串,而 port 包含好的信息.>
因此,我的问题是:
如何在 Syscall
的参数中传递整个字符串,而不仅仅是第一个字符?
编辑
如果我通过 return &p[i], nil
在 StringToCString
中更改 return &p[0], nil
我获得了字符串的第 i 个字符...所以问题肯定存在,我只是知道如何解决它...
在 Go 中将字符串传递给 Syscall 的参数
如何在 [Windows] Syscall 的参数中传递整个字符串?
<小时>
一个明显的答案是查看 Go 标准库,它进行了许多 Windows 系统调用.
<小时><块引用>golang.org/x/sys/windows
func UTF16FromString(s string) ([]uint16, error)
UTF16FromString 返回 UTF-8 字符串 s 的 UTF-16 编码,添加了终止 NUL.如果 s 在任何位置包含一个 NUL 字节位置,它返回 (nil, syscall.EINVAL).
func UTF16PtrFromString(s string) (*uint16, error)
UTF16PtrFromString 返回指向 UTF-8 的 UTF-16 编码的指针字符串 s,添加了终止 NUL.如果 s 包含一个 NUL 字节在任何位置,它返回 (nil, syscall.EINVAL).
func UTF16ToString(s []uint16) 字符串
UTF16ToString 返回 UTF-16 序列 s 的 UTF-8 编码,删除了终止 NUL.
I would like to use a C function compiled into a DLL. Here is the C function that I would like to use:
int setProxy(const proxy_config* p_proxy);
It takes a const pointer to a C structure defined like this:
typedef struct
{
char *host_address;
int port;
char *username;
char *password;
} proxy_config;
To do so, I transformed this C_structure into a Go equivalent as follows:
type proxy_configuration struct {
host_address *uint16
port int
username *uint16
password *uint16
}
To convert the strings, I use the following function:
func StringToCString(s string) (*uint16, error) {
for i := 0; i < len(s); i++ {
if s[i] == 0 {
return nil, errors.New("Problem with the string : "+s)
}
}
p := utf16.Encode([]rune(s + "\x00"))
return &p[0], nil
}
Then I call it:
import (
"syscall"
"unsafe"
)
func SetProxy(host_address string, port int, username string, password string) error {
[...Conversion code from Go string to Struct...]
var nargs uintptr = 1
ret, _, callErr := syscall.Syscall(
uintptr(setProxy),
nargs,
uintptr(unsafe.Pointer(&proxy)),
0,
0,
)
}
where setProxy
is the result of syscall.GetProcAddress(DLL,"setProxy")
The problem is that, when I have a look at the logs generated by the DLL, all the *uint16
contains only one character and not the whole string whereas port contains the good information.
Thus, my question is:
How can I pass the whole strings in the parameters of Syscall
and not just the first character?
EDIT
If I change return &p[0], nil
in the StringToCString
by return &p[i], nil
I obtain the i-th character of the string... So the problem is definely there, I just do know how to fix it...
Pass String to argument of Syscall in Go
How can I pass the whole strings in the parameters of [Windows] Syscall?
An obvious answer is to look at the Go standard libraries, which make many Windows syscalls.
golang.org/x/sys/windows
func UTF16FromString(s string) ([]uint16, error)
UTF16FromString returns the UTF-16 encoding of the UTF-8 string s, with a terminating NUL added. If s contains a NUL byte at any location, it returns (nil, syscall.EINVAL).
func UTF16PtrFromString(s string) (*uint16, error)
UTF16PtrFromString returns pointer to the UTF-16 encoding of the UTF-8 string s, with a terminating NUL added. If s contains a NUL byte at any location, it returns (nil, syscall.EINVAL).
func UTF16ToString(s []uint16) string
UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s, with a terminating NUL removed.
这篇关于在 Go 中将字符串传递给 Syscall 的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!