我是 Go 的新手,我想翻译一些我必须去 Go 的 C/C++ 代码,但我没能做到。问题出在两个地方:如何初始化我定义的结构以及如何执行“memcopy”
我说的代码是这样的:http://play.golang.org/p/e8N255qEAk 第 69 和 74 行。
我想“翻译”成 Go 的 C/C++ 代码是这样的:
typedef char xchr;
typedef int xint;
typedef double xdob;
typedef float xflt;
typedef struct
{
xint p;
xdob lat_lon_ele[3];
xflt psi_the_phi[3];
xflt gear_flap_vect[3];
}VEH1;
avio.p = 0;
avio.lat_lon_ele[0] = 47.460058;
avio.lat_lon_ele[1] = -122.32104;
avio.lat_lon_ele[2] = 8000.000;
avio.psi_the_phi[0] = 110.5;
avio.psi_the_phi[1] = 0.0;
avio.psi_the_phi[2] = 0.0;
avio.gear_flap_vect[0] = 1.0;
avio.gear_flap_vect[1] = 0.0;
avio.gear_flap_vect[2] = 0.0;
VEH1* av = &avio;
xchr data_send[6];
data_send[0]='V';
data_send[1]='E';
data_send[2]='H';
data_send[3]='1';
data_send[4]=0;
memcpy(&data_send[5],av,sizeof(VEH1)); // load in the data
Go 代码如下所示:
type xchr int8
type xint int
type xdob float64
type xflt float32
type VEH1 struct {
p xint
lat_lon_ele [3]xdob
psi_the_phi [3]xflt
gear_flap_vect [3]xflt
}
type VEHA struct {
num_p xint
lat_lon_ele [10][3]xdob
psi_the_phi [10][3]xflt
gear_flap_vect [10][3]xflt
lat_view, lon_view, ele_view xdob
psi_view, the_view, phi_view xflt
}
var avio VEH1
avio = &VEH1{0, {47.460058, -122.32104, 8000.000}, {110.5, 0.0, 0.0}, {1.0, 0.0, 0.0}}
data_send := [6]xchr{'V', 'E', 'H', '1', 0, 0}
copy(data_send[5:5], avio);
谢谢!
最佳答案
所以基本上给出了这些基本类型:
type xchr int8
type xint int
type xdob float64
type xflt float32
您想复制以下 struct 类型的值的字节(内存表示):
type VEH1 struct { // 52 bytes total
p xint // 4 bytes (READ BELOW)
lat_lon_ele [3]xdob // 24 bytes
psi_the_phi [3]xflt // 12 bytes
gear_flap_vect [3]xflt // 12 bytes
}
请注意,Go 中 int 的长度取决于平台,它可能是 32 位或 64 位,具体取决于您编译到的目标体系结构。这会导致依赖于平台的行为,所以让我们暂时将其修复为 int32:
type xint int32
上面的struct 的字节大小是这样计算的。如果您需要 int64,只需更改它并在大小计算中添加额外的 4 个字节。
接下来,您希望将结果放入一个元素类型为 xchr 的数组中。您需要一个足够大的数组,即“前缀”为 “VEH1”,后跟上述 struct 的数据。所以它的大小必须为 4+sizeof(VEH1),即 56。
在Go中将一种类型的字节复制到另一种类型的内存空间,你可以做到unsafe包装及其一般Pointer类型。任何指针都可以转换为 unsafe.Pointer 并且 unsafe.Pointer 可以转换为任何指针类型,因此这是不同指针类型之间的“网关”。
您可以获取 VHE1 的 struct 值的地址,将其转换为 Pointer,并将结果转换为 Pointer 指向目标数据类型的指针。取消引用指针,现在您已经拥有其他类型的值。
内置 copy()只能与 slice 一起使用,因此首先您需要对数据数组进行 slice ,以便能够将它们传递给 copy()。
你可以这样做:
avio := VEH1{0, [3]xdob{47.460058, -122.32104, 8000.000},
[3]xflt{110.5, 0.0, 0.0}, [3]xflt{1.0, 0.0, 0.0}}
fmt.Printf("%+v\n", avio)
pavio := unsafe.Pointer(&avio)
pavio_arr := *((*[52]xchr)(pavio))
data_send := [56]xchr{'V', 'E', 'H', '1'}
n := copy(data_send[4:], pavio_arr[:])
fmt.Printf("Copied %d bytes\n", n)
fmt.Printf("%+v\n", data_send)
输出,包裹以适应屏幕:
{p:0 lat_lon_ele:[47.460058 -122.32104 8000] psi_the_phi:[110.5 0 0]
gear_flap_vect:[1 0 0]}
Copied 52 bytes
[86 69 72 49 0 0 0 0 0 0 0 0 -81 33 56 46 -29 -70 71 64 77 45 91 -21 -117
-108 94 -64 0 0 0 0 0 64 -65 64 0 0 -35 66 0 0 0 0 0 0 0 0 0 0 -128 63 0 0 0 0]
尝试 Go Playground 上的工作演示.
[]byte如果您想要 []byte 结果(例如,您想要将结果写入 io.Writer ),则使用 [56]byte 类型作为 data_send,当然还有将 pavio 转换为 *[52]byte:
pavio := unsafe.Pointer(&avio)
pavio_arr := *((*[52]byte)(pavio))
data_send := [56]byte{'V', 'E', 'H', '1'}
n := copy(data_send[4:], pavio_arr[:])
关于arrays - Golang - 结构、初始化和 memcpy - 什么是正确的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30908818/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%