(The key is to ensure that the method gets specialized for different types 
with the parametric `::Type{T}` in the signature instead of `T::DataType`).

On Tuesday, March 24, 2015 at 12:10:59 PM UTC-4, Stefan Karpinski wrote:
>
> This seems like it works fine to me (on both 0.3 and 0.4):
>
> immutable Test
> x::Float32
> y::Int64
> z::Int8
> end
>
> julia> a = [Test(1,2,3)]
> 1-element Array{Test,1}:
>  Test(1.0f0,2,3)
>
> julia> b = copy(reinterpret(UInt8, a))
> 24-element Array{UInt8,1}:
>  0x00
>  0x00
>  0x80
>  0x3f
>  0x03
>  0x00
>  0x00
>  0x00
>  0x02
>  0x00
>  0x00
>  0x00
>  0x00
>  0x00
>  0x00
>  0x00
>  0x03
>  0xe0
>  0x82
>  0x10
>  0x01
>  0x00
>  0x00
>  0x00
>
> julia> prim_read{T}(::Type{T}, data::Array{Uint8,1}, offset::Int) = 
> unsafe_load(convert(Ptr{T}, pointer(data) + offset))
> prim_read (generic function with 1 method)
>
> julia> prim_read(Test, b, 0)
> Test(1.0f0,2,3)
>
> julia> @code_native prim_read(Test, b, 0)
> .section __TEXT,__text,regular,pure_instructions
> Filename: none
> Source line: 1
> push RBP
> mov RBP, RSP
> Source line: 1
> mov RCX, QWORD PTR [RSI + 8]
> vmovss XMM0, DWORD PTR [RCX + RDX]
> mov RAX, QWORD PTR [RCX + RDX + 8]
> mov DL, BYTE PTR [RCX + RDX + 16]
> pop RBP
> ret
>
>
> On Tue, Mar 24, 2015 at 5:04 PM, Simon Danisch <[email protected] 
> <javascript:>> wrote:
>
>> There is a high chance that I simply don't understand llvmcall well 
>> enough, though ;)
>>
>> Am Montag, 23. März 2015 20:20:09 UTC+1 schrieb Sebastian Good:
>>>
>>> I'm trying to read some binary formatted data. In C, I would define an 
>>> appropriately padded struct and cast away. Is is possible to do something 
>>> similar in Julia, though for only one value at a time? Philosophically, I'd 
>>> like to approximate the following, for some simple bittypes T (Int32, 
>>> Float32, etc.)
>>>
>>> T read<T>(char* data, size_t offset) { return *(T*)(data + offset); }
>>>
>>> The transliteration of this brain-dead approach results in the 
>>> following, which seems to allocate a boxed Pointer object on every 
>>> invocation. The pointer function comes with ample warnings about how it 
>>> shouldn't be used, and I imagine that it's not polite to the garbage 
>>> collector.
>>>
>>> prim_read{T}(::Type{T}, data::AbstractArray{Uint8, 1}, byte_number) = 
>>> unsafe_load(convert(Ptr{T}, pointer(data, byte_number)))
>>>
>>> I can reinterpret the whole array, but this will involve a division of 
>>> the offset to calculate the new offset relative to the reinterpreted array, 
>>> and it allocates an array object. 
>>>
>>> Is there a better way to simply read the machine word at a particular 
>>> offset in a byte array? I would think it should inline to a single assembly 
>>> instruction if done right.
>>>     
>>>
>>
>

Reply via email to