Clang.jl icon indicating copy to clipboard operation
Clang.jl copied to clipboard

Using `fieldnames` (and similar) for wrapped C `union`s

Open JoshuaLampert opened this issue 1 year ago • 2 comments

Currently, C unions and structs containing a union are wrapped as a julia struct having one field data with overwritten Base.getproperty and Base.setproperty! functions, e.g.

union testunion
{
    int y;
};

struct teststruct
{
  int x;
  union testunion p;
};

is wrapped as

using CEnum

struct testunion
    data::NTuple{4, UInt8}
end

function Base.getproperty(x::Ptr{testunion}, f::Symbol)
    f === :y && return Ptr{Cint}(x + 0)
    return getfield(x, f)
end

function Base.getproperty(x::testunion, f::Symbol)
    r = Ref{testunion}(x)
    ptr = Base.unsafe_convert(Ptr{testunion}, r)
    fptr = getproperty(ptr, f)
    GC.@preserve r unsafe_load(fptr)
end

function Base.setproperty!(x::Ptr{testunion}, f::Symbol, v)
    unsafe_store!(getproperty(x, f), v)
end

struct teststruct
    data::NTuple{8, UInt8}
end

function Base.getproperty(x::Ptr{teststruct}, f::Symbol)
    f === :x && return Ptr{Cint}(x + 0)
    f === :p && return Ptr{testunion}(x + 4)
    return getfield(x, f)
end

function Base.getproperty(x::teststruct, f::Symbol)
    r = Ref{teststruct}(x)
    ptr = Base.unsafe_convert(Ptr{teststruct}, r)
    fptr = getproperty(ptr, f)
    GC.@preserve r unsafe_load(fptr)
end

function Base.setproperty!(x::Ptr{teststruct}, f::Symbol, v)
    unsafe_store!(getproperty(x, f), v)
end

This doesn' t allow to properly use fieldnames or propertynames (and similar functions) as they return (:data,) (or similar) and not the actual fields you can access by getproperty. The problem came up in https://github.com/trixi-framework/P4est.jl/issues/72.

cc @ranocha, @sloede

JoshuaLampert avatar Mar 25 '23 17:03 JoshuaLampert

dup of #316?

Gnimuc avatar Mar 26 '23 02:03 Gnimuc

It isn't really the same issue? In #316 the autocomplete doesn't work for the Ptr{T} type, but it would work for struct T directly. In this issue, there is only the ":data" field in the struct. Way to the solution is probably quite different?

thomvet avatar Dec 10 '23 11:12 thomvet