Skip to content

Unnecessary copy when passing structs to C++ #77

@apple1417

Description

@apple1417
Betty = unrealsdk.find_object(
    "ProjectileDefinition",
    "GD_Anemone_GrenadeMods.Projectiles.Grenade_BouncingBetty_Jump",
)
NewBetty = unrealsdk.construct_object(
    "ProjectileDefinition",
    Betty.Outer,
    "New_Betty",
)
NewBetty.BodyComposition = Betty.BodyComposition

This last line actually makes two copies. In C++, the assignment is done with:

set_property<T>(prop, i, base_addr, py::cast<value_type>(value_seq[i]));

It turns out, the py::cast call makes a copy of the struct, and the WrappedStruct copy constructor makes a full copy of it's contents. This temporary is then copied onto NewBetty.

Since Python usually deals entirely with references, and you need to explicitly call copy.copy(struct), it seems relatively intuitive to make passing a struct to C++ also pass a reference - it's just a technical problem. I suspect we could do this with a custom type caster - I just don't know enough about pybind internals.

On a related note, I would like to delete the WrappedStruct copy constructor in unrealsdk, and instead have two methods to make you explicitly pick if you want a reference copy or a full value copy. We cannot currently do this, since pybind breaks without a copy constructor, would need this custom type caster first. We also obviously cannot change the existing copy constructor to make a reference copy instead, since there's code out there relying on it being a full copy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions