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

问题描述 投票:1回答:1

我想使用编译为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的参数中传递整个字符串,而不仅仅是第一个字符?


编辑

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

c windows go dll type-conversion
1个回答
2
投票

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

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


一个明显的答案是看一下执行许多Windows syscall的Go标准库。


package windows

golang.org/x/sys/windows

func UTF16FromString

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

UTF16FromString返回UTF-8字符串的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) string

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

© www.soinside.com 2019 - 2024. All rights reserved.