syscall – How to use LPWSTR in Go?

huangapple go评论72阅读模式
英文:

syscall - How to use LPWSTR in Go?

问题

我正在尝试为Go语言创建一个Windows MMDevice API的轻量级封装,但是在处理Windows字符串的数据类型时遇到了问题。

根据IMMDevice::GetId方法的文档,它接受以下参数:

HRESULT GetId(
    [out] LPWSTR *ppstrId
);

以下是对应于上述方法的Go代码(github.com/moutend/ywca/immdevice_windows.go:13):

func getId(mmd *IMMDevice, strId *uint16) (err error) {
    hr, _, _ := syscall.Syscall(
        mmd.VTable().GetId,
        2,
        uintptr(unsafe.Pointer(mmd)),
        uintptr(unsafe.Pointer(strId)),
        0)
    // ...
}

我理解的是LPWSTR是指向uint16值数组的指针,但这会导致无效指针错误。
在这种情况下,我应该使用什么类型?谢谢。

英文:

I'm trying to create a thin wrapper of Windows MMDevice API for Go, and I faced the problem about Windows data types for strings.
According to the documentation of IMMDevice::GetId method, it takes the parameter below:

HRESULT GetId(
    [out] LPWSTR *ppstrId
);

And here is my Go code that corresponds to the method above. (github.com/moutend/ywca/immdevice_windows.go:13)

func getId(mmd *IMMDevice, strId *uint16) (err error) {
    hr, _, _ := syscall.Syscall(
        mmd.VTable().GetId,
        2,
        uintptr(unsafe.Pointer(mmd)),
        uintptr(unsafe.Pointer(strId)),
        0)
    // ...
}

My understand is that the LPWSTR is the pointer to the array of uint16 values, but it causes invalid pointer error.
What type should I use in this case? Thanks.

答案1

得分: 1

这是一个指向指针的指针。LPWSTR 类型是 wchar_t*,因此该方法的参数是 wchar_t**

你没有传入一个字符串缓冲区供该方法填充。该方法将使用 CoTaskMemAlloc 分配内存,并在填充完成后将该内存地址返回给你。你需要使用 CoTaskMemAlloc 释放这块内存。

英文:

It is a pointer to a pointer. The LPWSTR type is a wchar_t* and therefor the parameter in that method is a wchar_t**.

You are not passing in a string buffer for the method to fill. The method will allocate memory with CoTaskMemAlloc and return this memory address back to you after it has been filled. You are responsible for freeing this memory with CoTaskMemAlloc.

答案2

得分: 0

首先要做的是阅读Windows函数的文档。

> IMMDevice::GetId方法
>
> HRESULT GetId(
> [out] LPWSTR *ppstrId
> );
>
> 参数
>
> ppstrId [out]
>
> 指向指针变量的指针,方法将在其中写入一个以空字符结尾的宽字符字符串,该字符串包含终结点设备的ID。方法为字符串分配存储空间。当不再需要时,调用方负责通过调用CoTaskMemFree函数释放存储空间。如果GetId调用失败,*ppstrId为NULL。有关CoTaskMemFree的信息,请参阅Windows SDK文档。
>
> 返回值
>
> 如果方法成功,它将返回S_OK。如果失败,可能的返回代码包括但不限于以下表中所示的值。

特别是"ppstrId [out] 指向指针变量...",你有strId *uint16*pstrId,而我期望你有strId **uint16*ppstrId

英文:

The first thing to do is read the documentation for the Windows function.

> IMMDevice::GetId
> method
,
>
> HRESULT GetId(
> [out] LPWSTR *ppstrId
> );
>
> Parameters
>
> ppstrId [out]
>
> Pointer to a pointer variable into which the method writes the address
> of a null-terminated, wide-character string containing the endpoint
> device ID. The method allocates the storage for the string. The caller
> is responsible for freeing the storage, when it is no longer needed,
> by calling the CoTaskMemFree function. If the GetId call fails,
> *ppstrId is NULL. For information about CoTaskMemFree, see the Windows SDK documentation.
>
> Return value
>
> If the method succeeds, it returns S_OK. If it fails, possible return
> codes include, but are not limited to, the values shown in the
> following table.

In particular, "ppstrId [out] Pointer to a pointer variable ..." You have strId *uint16 or *pstrId when I would expect you to have strId **uint16 or *ppstrId.

huangapple
  • 本文由 发表于 2017年2月21日 10:32:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/42357652.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定