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.
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
.
The first thing to do is read the documentation for the Windows function.
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
.