问题描述
我正在尝试通过Go调用idm api。我检查了Python和C#的实现,并在Go中编写了一个演示,但无法运行,并显示以下错误,因此有人可以告诉我原因,还是提供可以调用api的演示?
Exception 0xc0000005 0x0 0xffffffffffffffff 0x7ff973decc86
PC=0x7ff973decc86
syscall.Syscall9(0x7ff973e61f10,0x9,0x1c30f1a55f8,0x1c30f1e0fe8,0x1c30f1cb478,0x1c30f1cb4f8,0x1c30f1cb798,0x1c30f1cb518,0x1c30f1cb578,0x1c30f1cba78,...)
C:/Go/src/runtime/syscall_windows.go:214 +0xf2
main.(*ICIDMLinkTransmitter).SendLinkToIDM(0x1c30f1d20e8,0x1c300000000,...)
C:/D/gocode/idm/main.go:52 +0x145
main.(*IDMLinkTransmitter).SendLinkToIDM(0xc000006028,0xfdf9aa,0x16,0x0,...)
C:/D/gocode/idm/main.go:97 +0x2fc
main.main()
C:/D/gocode/idm/main.go:130 +0x105
rax 0x70007400740068
rbx 0x1082f80
rcx 0x69d75ffc60
rdi 0x3
rsi 0x69d75ffc60
rbp 0x69d75ffc30
rsp 0x69d75ff880
r8 0x3
r9 0x1c30f1cb4f8
r10 0x1c30f1d20e8
r11 0x1c30f1cba78
r12 0x11
r13 0x10
r14 0x1c30f1a55f8
r15 0x2030000
rip 0x7ff973decc86
rflags 0x10202
cs 0x33
fs 0x53
gs 0x2b
exit status 2
这是我的代码: https://github.com/Greyh4t/callidm
这是api手册: http://www.internetdownloadmanager.com/support/idm_api.html
这是Python的实现: Use IDM(Internet Download Manager) API with python
解决方法
几个星期后,我自己解决了这个问题。在研究了C代码编写之后,我发现发生此错误是因为结构本身未在syscall中传递。正确的代码如下。
package idm
import (
"syscall"
"unsafe"
"github.com/lxn/win"
)
type ICIDMLinkTransmitter2Vtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
SendLinkToIDM uintptr
SendLinkToIDM2 uintptr
SendLinksArray uintptr
}
type ICIDMLinkTransmitter2 struct {
vtbl *ICIDMLinkTransmitter2Vtbl
}
func (obj *ICIDMLinkTransmitter2) Release() uint32 {
r1,_,_ := syscall.Syscall(
obj.vtbl.Release,1,uintptr(unsafe.Pointer(obj)),)
return uint32(r1)
}
func (obj *ICIDMLinkTransmitter2) SendLinkToIDM(url,referer,cookies,data,user,password,localPath,localFileName *uint16,flags int32) uint32 {
r1,_ := syscall.Syscall12(
obj.vtbl.SendLinkToIDM,10,uintptr(unsafe.Pointer(url)),uintptr(unsafe.Pointer(referer)),uintptr(unsafe.Pointer(cookies)),uintptr(unsafe.Pointer(data)),uintptr(unsafe.Pointer(user)),uintptr(unsafe.Pointer(password)),uintptr(unsafe.Pointer(localPath)),uintptr(unsafe.Pointer(localFileName)),uintptr(flags),)
return uint32(r1)
}
func (obj *ICIDMLinkTransmitter2) SendLinkToIDM2(url,flags int32,reserved1,reserved2 *win.VARIANT) uint32 {
r1,_ := syscall.Syscall12(
obj.vtbl.SendLinkToIDM2,12,uintptr(unsafe.Pointer(reserved1)),uintptr(unsafe.Pointer(reserved2)),)
return uint32(r1)
}
func (obj *ICIDMLinkTransmitter2) SendLinksArray(location *uint16,pLinksArray *win.VARIANT) uint32 {
r1,_ := syscall.Syscall(
obj.vtbl.SendLinksArray,3,uintptr(unsafe.Pointer(location)),uintptr(unsafe.Pointer(pLinksArray)),)
return uint32(r1)
}
完整的代码在这里 https://github.com/Greyh4t/idm