在使用Golang绑定库torrent时,如何转换为“alert”类型。

huangapple go评论85阅读模式
英文:

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 &quot;save_resume_data_alert&quot;, I pick it up and have to CAST it as written in libtorrent documentation

...
        save_resume_data_alert const* rd = alert_cast&lt;save_resume_data_alert&gt;(a);
...

But i really have not idea how to cast it in golang! Current code:

package main

import (
	lt &quot;github.com/steeve/libtorrent-go&quot;

	&quot;log&quot;
	&quot;time&quot;
)

func main() {

	randomTorrent := lt.NewAdd_torrent_params()
	randomTorrent.SetUrl(&quot;PUT A MAGNET LINK HERE&quot;)
	randomTorrent.SetSave_path(&quot;.&quot;)

	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(&quot;Alert timeout occurred!&quot;)
			}

			alert := torrentSession.Pop_alert()
			switch alert.What() {
			default:
				log.Printf(&quot;Alert: %#v&quot;, alert.What())
			case &quot;metadata_received_alert&quot;:
				log.Println(&quot;Received Metadata!! finally!&quot;)
				torrentHandle.Save_resume_data()
			case &quot;save_resume_data_alert&quot;:
				log.Println(&quot;Wrote Metadata!&quot;)
				// need to actually write the resume_data :( can&#39;t find how
			case &quot;save_resume_data_failed_alert&quot;:
				log.Println(&quot;Failed Metadata!&quot;)
			}
		}
	}()

	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 &quot;save_resume_data_alert&quot;:
  log.Println(&quot;Wrote Metadata!&quot;)
  // need to actually write the resume_data :( can&#39;t find how
  SaveRDAlert := lt.SwigcptrSave_resume_data_alert(alert.Swigcptr())
  log.Printf(&quot;Resume Data: %#v&quot;, SaveRDAlert.GetResume_data())

huangapple
  • 本文由 发表于 2014年12月17日 19:35:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/27524688.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定