On Mon, Oct 12, 2015 at 6:46 PM, Matt <[email protected]> wrote: > Ok. It works know. I was stuck to the last two lines. I defined > is_system_missing::Cint > is_considered_missing::Cint. > > instead of an UInt8 > > A last question: I actually have the structure itself as an argument, not a > pointer to the structure. Is the best way to convert v.union to the right > type > unsafe_load(convert(Ptr{T}, pointer_from_objref(val))) > ?
Don't use `pointer_from_objref` > The issue with reinterpret is that it fails when the new type fits in less > than a 64-bit field Cast to a smaller integer first should work. (Although you might need to worry a little about the endianess). > > On Monday, October 12, 2015 at 3:55:53 PM UTC-4, Steven G. Johnson wrote: >> >> >> >> On Monday, October 12, 2015 at 3:30:18 PM UTC-4, Douglas Bates wrote: >>> >>> On Monday, October 12, 2015 at 11:24:06 AM UTC-5, Matt wrote: >>>> >>>> ReadStat is an excellent C library by Evan Millers that allows to read >>>> files from Stata, SPSS and SAS. >>>> Evan wrote a wrapper for ReadStat in the Dataread.jl package >>>> https://github.com/WizardMac/DataRead.jl >>>> However, the package was not updated with the most recent API of >>>> ReadStat. >>>> I've been trying to solve this without success (see the WIP pull request >>>> in the repository) >>>> The hard part is to write a Julia function (handle_value) that accepts a >>>> C structure with a union field. >>>> >>>> typedef struct readstat_value_s { >>>> union { >>>> char char_value; >>>> float float_value; >>>> double double_value; >>>> int16_t i16_value; >>>> int32_t i32_value; >>>> char *string_value; >>>> } v; >>>> readstat_types_t type; >>>> char tag; >>>> int is_system_missing:1; >>>> int is_considered_missing:1; >>>> } readstat_value_t; >> >> >> >> Something like the following should work, because the union types all fit >> into a 64-bit field and will be aligned as such: >> >> immutable readstat_value_t >> union::Int64 >> typ::Cint # enum >> tag::Cchar >> bits::UInt8 # bitfield (first two bits are is_system_missing and >> is_considered_missing) >> end >> >> function handle_value(p::Ptr{readstat_value_t}) >> v = unsafe_load(p) >> if v.tag == READSTAT_TYPE_DOUBLE >> value = unsafe_load(convert(Ptr{Cdouble}, p)) >> ...do stuff... >> else if v.tag == READSTAT_TYPE_STRING >> value = bytestring(unsafe_load(convert(Ptr{Cchar}, p))) >> ... do stuff... >> else ... >> .... >> end >> end >> >
