结构体转换成ByteArray的问题


mutable struct _intellij_info_struct
  width::Int32
  flag::Int32
  size::Int32
  raw::String
end

function _intellij_x_to_bytes(x)
   sz = sizeof(x)
   if VERSION >= v"0.7.0"
     ba = Vector{UInt8}(sz)
     src_ptr = convert(Ptr{UInt8}, pointer_from_objref(x))
     unsafe_copyto!(pointer(ba), src_ptr, sz)
   end
   return ba
end

# 过程略.....
  println(size)
  println(text)
ref=_intellij_info_struct(-1,-1,size,text)
bytes = _intellij_x_to_bytes(ref)
println(bytes)

结果

42
Any[Any["asd", "8 bytes", "233", "Int64"]]

┌ Warning: `Array{T, 1}(m::Int) where T` is deprecated, use `Array{T, 1}(undef, m)` instead.
│   caller = _intellij_x_to_bytes(::_intellij_info_struct) at IntelliJ.jl:45
└ @ Main ~/git/julia-intellij/res/org/ice1000/julia/lang/action/IntelliJ.jl:45
UInt8[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xa2, 0xca, 0x5b, 0x23, 0x7f, 0x00, 0x00]

前两个 -1 没问题,都变成了四个 0xff,但是第三个数字是42 也就是这个 0x2a,这里直接给我搞成了 0x2a000000,也就意味着把42的四个字节位搞反了……

endianness? little endian 有 built-in 函数可以转

这个不是 isbits type,你确定最后一个 String 的 alignment 就是普通连续的? 手动凑比较安全一点?

julia> using Blobs

julia> struct _intellij_info_struct
         width::Int32
         flag::Int32
         size::Int32
         raw::Ptr{UInt8}
       end

julia> isbitstype(_intellij_info_struct)
true

julia> p = Libc.malloc(sizeof(_intellij_info_struct))
Ptr{Nothing} @0x00007fa3aa53d510

julia> x = Blob{_intellij_info_struct}(p, 0, sizeof(_intellij_info_struct))
Blob{_intellij_info_struct}(Ptr{Nothing} @0x00007fa3aa53d510, 0, 24)

julia> x.width[]=-1; x.flag[]=-1; x.size[]=3;

julia> x.width[], x.flag[], x.size[]
(-1, -1, 3)

julia> pointer("abc")
Ptr{UInt8} @0x000000011b2601b8

julia> x.raw[] = pointer("abc")
Ptr{UInt8} @0x000000011c72ecb8

julia> unsafe_string(x.raw[])
"abc"

julia> unsafe_wrap(Array, Ptr{UInt8}(pointer(x.width)), 4)
4-element Array{UInt8,1}:
 0xff
 0xff
 0xff
 0xff

julia> unsafe_wrap(Array, Ptr{UInt8}(pointer(x.flag)), 4)
4-element Array{UInt8,1}:
 0xff
 0xff
 0xff
 0xff

julia> unsafe_wrap(Array, Ptr{UInt8}(pointer(x.size)), 4)
4-element Array{UInt8,1}:
 0x03
 0x00
 0x00
 0x00

julia> unsafe_wrap(Array, x.raw[], 3)
3-element Array{UInt8,1}:
 0x61
 0x62
 0x63