在 Go 中将字符串传递给 Syscall 的参数 [英] Pass String to argument of Syscall in Go

查看:36
本文介绍了在 Go 中将字符串传递给 Syscall 的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用编译成 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,)}

其中 setProxysyscall.GetProcAddress(DLL,"setProxy")

的结果

问题是,当我查看 DLL 生成的日志时,所有 *uint16 只包含一个字符而不是整个字符串,而 port 包含好的信息.>

因此,我的问题是:

如何在 Syscall 的参数中传递整个字符串,而不仅仅是第一个字符?

<小时>

编辑

如果我通过 return &p[i], nilStringToCString 中更改 return &p[0], nil我获得了字符串的第 i 个字符...所以问题肯定存在,我只是知道如何解决它...

解决方案

在 Go 中将字符串传递给 Syscall 的参数

如何在 [Windows] Syscall 的参数中传递整个字符串?

<小时>

一个明显的答案是查看 Go 标准库,它进行了许多 Windows 系统调用.

<小时><块引用>

包窗口

golang.org/x/sys/windows

func UTF16FromString

func UTF16FromString(s string) ([]uint16, error)

UTF16FromString 返回 UTF-8 字符串 s 的 UTF-16 编码,添加了终止 NUL.如果 s 在任何位置包含一个 NUL 字节位置,它返回 (nil, syscall.EINVAL).

func UTF16PtrFromString

func UTF16PtrFromString(s string) (*uint16, error)

UTF16PtrFromString 返回指向 UTF-8 的 UTF-16 编码的指针字符串 s,添加了终止 NUL.如果 s 包含一个 NUL 字节在任何位置,它返回 (nil, syscall.EINVAL).

func UTF16ToString

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.


package windows

golang.org/x/sys/windows

func UTF16FromString

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

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆