【问题标题】:Pass String to argument of Syscall in Go将字符串传递给 Go 中 Syscall 的参数
【发布时间】:2020-06-01 16:12:19
【问题描述】:

我想使用编译成 DLL 的 C 函数。 这是我想使用的 C 函数:

int setProxy(const proxy_config* p_proxy);

它需要一个指向 C 结构的 const 指针,定义如下:

typedef struct
{
    char *host_address; 
    int port;           
    char *username;     
    char *password;     
} proxy_config;

为此, 我将这个 C_structure 转换为 Go 等价物,如下所示:

type proxy_configuration struct {
    host_address *uint16 
    port int             
    username *uint16     
    password *uint16     
}

为了转换字符串,我使用以下函数:

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
}

那我叫它:

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,
    )
}

其中setProxysyscall.GetProcAddress(DLL,"setProxy") 的结果

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

因此,我的问题是:

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


编辑

如果我将StringToCString 中的return &amp;p[0], nil 更改为return &amp;p[i], nil 我获得了字符串的第 i 个字符...所以问题确实存在,我只是知道如何解决它...

【问题讨论】:

    标签: c windows go dll type-conversion


    【解决方案1】:

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

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


    一个明显的答案是查看 Go 标准库,它会产生许多 Windows 系统调用。


    package 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 在 任何位置,它都会返回 (nil, syscall.EINVAL)。

    func UTF16ToString

    func UTF16ToString(s []uint16) string
    

    UTF16ToString 返回 UTF-16 序列 s 的 UTF-8 编码, 删除了终止 NUL。

    【讨论】:

    • 我确实尝试过这些功能。但它不会改变结果。对我来说,我传递结构的方式似乎有问题......从 String 到 UTF16 和 UTF16 到 String 的转换已经过测试。所以这部分没问题...:/
    猜你喜欢
    • 2021-11-02
    • 2022-01-09
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多