英文:
Utilizing OLE in Go results in "The tag is invalid" error
问题
我正在尝试在Go语言中使用OLE来设置Windows 10上的默认音频输出源。我使用了两个第三方包来完成这个任务:
我遇到的问题是,函数pcv.SetDefaltEndpoint()
没有设置默认的输出源,而是返回一个简单的错误消息,内容为The tag is invalid
。
我使用了这个包的源代码(用C#编写)来确认我提供的GUID和设备ID是正确的,但是我仍然没有成功。
https://github.com/sirWest/AudioSwitch
非常感谢您的帮助。谢谢大家抽出时间来帮助我。
编辑:我刚刚意识到我错误地使用了syscall.SyscallN
。似乎旧的用法是提供参数的数量,但是syscallN
不需要这个。在纠正了这个错误之后,我现在得到了这个错误:A null reference pointer was passed to the stub.
尽管所有的变量都不是空指针。
英文:
I am attempting to utilize OLE in go to set the default audio output source on Windows 10. I am using 2 third-party packages to accomplish this:
The problem that I am having is that the function pcv.SetDefaltEndpoint()
is not setting the default output source but is instead returning an error that simply says The tag is invalid
.
package main
import (
"fmt"
"syscall"
"unsafe"
"github.com/go-ole/go-ole"
"github.com/moutend/go-wca/pkg/wca"
)
type IPolicyConfig struct {
ole.IUnknown
}
type IPolicyConfigVtbl struct {
ole.IUnknownVtbl
GetDeviceFormat uintptr
ResetDeviceFormat uintptr
SetDeviceFormat uintptr
GetProcessingPeriod uintptr
SetProcessingPeriod uintptr
GetShareMode uintptr
SetShareMode uintptr
GetPropertyValue uintptr
SetPropertyValue uintptr
SetDefaultEndpoint uintptr
SetEndpointVisibility uintptr
}
func (v *IPolicyConfig) VTable() *IPolicyConfigVtbl {
return (*IPolicyConfigVtbl)(unsafe.Pointer(v.RawVTable))
}
func (v *IPolicyConfig) SetDefaultEndpoint(deviceID string, eRole wca.ERole) (err error) {
err = pcvSetDefaultEndpoint(v, deviceID, eRole)
return
}
func pcvSetDefaultEndpoint(pcv *IPolicyConfig, deviceID string, eRole wca.ERole) (err error) {
var ptr *uint16
if ptr, err = syscall.UTF16PtrFromString(deviceID); err != nil {
return
}
hr, _, _ := syscall.SyscallN(
pcv.VTable().SetDefaultEndpoint,
3,
uintptr(unsafe.Pointer(pcv)),
uintptr(unsafe.Pointer(ptr)),
uintptr(uint32(eRole)))
if hr != 0 {
err = ole.NewError(hr)
}
return
}
func main() {
if err := ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED); err != nil {
return
}
defer ole.CoUninitialize()
CPolicyConfigClientUID := ole.NewGUID("870AF99C-171D-4F9E-AF0D-E63DF40C2BC9")
IPolicyConfigUID := ole.NewGUID("F8679F50-850A-41CF-9C72-430F290290C8")
var pcv *IPolicyConfig
if err := wca.CoCreateInstance(CPolicyConfigClientUID, 0, wca.CLSCTX_ALL, IPolicyConfigUID, &pcv); err != nil {
return
}
defer pcv.Release()
fmt.Println(pcv.SetDefaultEndpoint("{0.0.0.00000000}.{81d9ff45-7f2a-4397-9885-0275cb01c816}", wca.EMultimedia))
}
I used the source code of this package (in C#) to confirm that the GUIDs and Device ID I'm supplying are correct but I'm still not having any luck.
https://github.com/sirWest/AudioSwitch
Any help would be greatly appreciated. Thank you all for your time.
EDIT: I just now realized that I was using syscall.SyscallN
incorrectly. It appears the old way of using it was to supply the number of arguments, but syscallN
does not need this. After correcting this, I'm now getting this error: A null reference pointer was passed to the stub.
despite all the variables being supplied to it are not null
答案1
得分: 1
我终于弄清楚了!在我的结构体中,第一个uintptr的单词是GetDeviceFormat
而不是GetMixFormat
。我希望我的痛苦和困扰能帮助到未来的某个人,即使是在5年后。
英文:
I finally figured it out! For the first uintptr in my struct I had the word GetDeviceFormat
not GetMixFormat
. I hope my pain and suffering helps somebody, even if it's 5 years in the future.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论