英文:
Casting an "alert" type in libtorrent, using Golang bindings
问题
我正在开发一个使用Golang的个人项目,使用libtorrent-go。
当我收到类型为"save_resume_data_alert"
的警报时,我会捕获它,并且需要按照libtorrent文档中的写法进行类型转换。
...
save_resume_data_alert const* rd = alert_cast<save_resume_data_alert>(a);
...
但是我真的不知道如何在Golang中进行类型转换!当前的代码如下:
package main
import (
lt "github.com/steeve/libtorrent-go"
"log"
"time"
)
func main() {
randomTorrent := lt.NewAdd_torrent_params()
randomTorrent.SetUrl("PUT A MAGNET LINK HERE")
randomTorrent.SetSave_path(".")
ec := lt.NewError_code()
torrentSession := lt.NewSession()
torrentSession.Set_alert_mask(status_notification + storage_notification)
torrentSession.Listen_on(lt.NewStd_pair_int_int(6900, 6999), ec)
if ec.Value() != 0 {
log.Println(ec.Message())
}
torrentHandle := torrentSession.Add_torrent(randomTorrent, ec)
if ec.Value() != 0 {
log.Println(ec.Message())
}
go func() {
for {
if torrentSession.Wait_for_alert(lt.Seconds(10)).Swigcptr() == 0 {
log.Println("Alert timeout occurred!")
}
alert := torrentSession.Pop_alert()
switch alert.What() {
default:
log.Printf("Alert: %#v", alert.What())
case "metadata_received_alert":
log.Println("Received Metadata!! finally!")
torrentHandle.Save_resume_data()
case "save_resume_data_alert":
log.Println("Wrote Metadata!")
// 需要实际写入resume_data :( 找不到如何写入
case "save_resume_data_failed_alert":
log.Println("Failed Metadata!")
}
}
}()
select {}
}
请注意,我只会翻译代码部分,不会回答关于翻译的问题。
英文:
I am developing a personal project in Golang, using libtorrent-go
When I do receive an alert of type "save_resume_data_alert"
, I pick it up and have to CAST it as written in libtorrent documentation
...
save_resume_data_alert const* rd = alert_cast<save_resume_data_alert>(a);
...
But i really have not idea how to cast it in golang! Current code:
package main
import (
lt "github.com/steeve/libtorrent-go"
"log"
"time"
)
func main() {
randomTorrent := lt.NewAdd_torrent_params()
randomTorrent.SetUrl("PUT A MAGNET LINK HERE")
randomTorrent.SetSave_path(".")
ec := lt.NewError_code()
torrentSession := lt.NewSession()
torrentSession.Set_alert_mask(status_notification + storage_notification)
torrentSession.Listen_on(lt.NewStd_pair_int_int(6900, 6999), ec)
if ec.Value() != 0 {
log.Println(ec.Message())
}
torrentHandle := torrentSession.Add_torrent(randomTorrent, ec)
if ec.Value() != 0 {
log.Println(ec.Message())
}
go func() {
for {
if torrentSession.Wait_for_alert(lt.Seconds(10)).Swigcptr() == 0 {
log.Println("Alert timeout occurred!")
}
alert := torrentSession.Pop_alert()
switch alert.What() {
default:
log.Printf("Alert: %#v", alert.What())
case "metadata_received_alert":
log.Println("Received Metadata!! finally!")
torrentHandle.Save_resume_data()
case "save_resume_data_alert":
log.Println("Wrote Metadata!")
// need to actually write the resume_data :( can't find how
case "save_resume_data_failed_alert":
log.Println("Failed Metadata!")
}
}
}()
select {}
}
答案1
得分: 1
如上所述,libtorrent-go
的开发者回答了我,所以我将这个答案转发出来,以备后用。
使用SWIG库在Golang中进行C++结构的转换在SWIG-Golang文档中有详细说明。
特别是在以下语句中:
> 给定接口类型的值,Go代码可以通过调用Swigcptr方法来检索C++类型的指针。
> 这将返回一个SwigcptrClassName类型的值,它只是一个uintptr的别名。
> 可以使用Go类型转换将此值转换为不同的C++类型,但请注意,此转换不会进行类型检查,
> 并且本质上等同于reinterpret_cast。这只应该用于非常特殊的情况,例如C++中使用dynamic_cast的情况。
在我上面发布的那段代码中,为了使其工作,需要进行以下操作:
case "save_resume_data_alert":
log.Println("Wrote Metadata!")
// 需要实际写入resume_data :( 找不到如何写入
SaveRDAlert := lt.SwigcptrSave_resume_data_alert(alert.Swigcptr())
log.Printf("Resume Data: %#v", SaveRDAlert.GetResume_data())
英文:
As stated above, libtorrent-go
developer answered me, so I am forwarding the answer for posterity reasons.
Casting C++ structures in Golang using SWIG library is documented in SWIG-Golang documentation.
In particular in this statement:
> Given a value of the interface type, Go code can retrieve the pointer
> to the C++ type by calling the Swigcptr method. This will return a
> value of type SwigcptrClassName, which is just a name for uintptr. A
> Go type conversion can be used to convert this value to a different
> C++ type, but note that this conversion will not be type checked and
> is essentially equivalent to reinterpret_cast. This should only be
> used for very special cases, such as where C++ would use a
> dynamic_cast.
In that particular piece of code I posted above, the following was necessary to make it work:
case "save_resume_data_alert":
log.Println("Wrote Metadata!")
// need to actually write the resume_data :( can't find how
SaveRDAlert := lt.SwigcptrSave_resume_data_alert(alert.Swigcptr())
log.Printf("Resume Data: %#v", SaveRDAlert.GetResume_data())
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论