胡说叔叔
我在我的Direct3D9 Go 包装器中遇到了类似的问题,请参阅这个线程,在那里我能够从纯 Go 调用 DirectX COM 函数。在您的代码中,您尝试调用proc.ConnectServer(...),但调用 a 的方法syscall.LazyProc是使用它的Call函数。查看 DllGetClassObject的文档,签名是HRESULT __stdcall DllGetClassObject( _In_ REFCLSID rclsid, _In_ REFIID riid, _Out_ LPVOID *ppv);这意味着您必须将这三个参数传递给proc.Callas uintptrs(Call期望所有参数都是uintptrs)。package mainimport "syscall"var ( xaSession = syscall.NewLazyDLL("XA_Session.dll") getClassObject = xaSession.NewProc("DllGetClassObject"))func main() { // TODO set these variables to the appropriate values var rclsid, riid, ppv uintptr ret, _, _ := getClassObject.Call(rclsid, riid, ppv) // ret is the HRESULT value returned by DllGetClassObject, check it for errors}请注意,您需要正确设置参数值,CLSID 和 IID 可能包含在库随附的 C 头文件中,我不知道这个 XA_Session 库。在这种ppv情况下,将是指向您创建的 COM 对象的指针。要使用 Go 中的 COM 方法,您可以创建包装器类型,前提是您知道它定义的所有 COM 方法及其正确顺序。所有 COM 对象都支持和函数QueryInterface,然后支持其他类型特定的方法。AddRefRelease假设您的 XA_Session 对象还支持这两个功能(同样,我不知道它真正支持什么,您必须查一下)int ConnectServer(int id)DisconnectServer()那么你可以做些什么来将它包装在 Go 中:package xasessionimport ( "syscall" "unsafe")// NewXASession casts your ppv from above to a *XASessionfunc NewXASession(ppv uintptr) *XASession { return (*XASession)(unsafe.Pointer(ppv))}// XASession is the wrapper object on which to call the wrapper methods.type XASession struct { vtbl *xaSessionVtbl}type xaSessionVtbl struct { // every COM object starts with these three QueryInterface uintptr AddRef uintptr Release uintptr // here are all additional methods of this COM object ConnectServer uintptr DisconnectServer uintptr}func (obj *XASession) AddRef() uint32 { ret, _, _ := syscall.Syscall( obj.vtbl.AddRef, 1, uintptr(unsafe.Pointer(obj)), 0, 0, ) return uint32(ret)}func (obj *XASession) Release() uint32 { ret, _, _ := syscall.Syscall( obj.vtbl.Release, 1, uintptr(unsafe.Pointer(obj)), 0, 0, ) return uint32(ret)}func (obj *XASession) ConnectServer(id int) int { ret, _, _ := syscall.Syscall( obj.vtbl.ConnectServer, // function address 2, // number of parameters to this function uintptr(unsafe.Pointer(obj)), // always pass the COM object address first uintptr(id), // then all function parameters follow 0, ) return int(ret)}func (obj *XASession) DisconnectServer() { syscall.Syscall( obj.vtbl.DisconnectServer, 1, uintptr(unsafe.Pointer(obj)), 0, 0, )}