Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bindings generator] generates invalid code on c# side #2582

Closed
cNori opened this issue May 10, 2024 · 5 comments · Fixed by #2591
Closed

[Bindings generator] generates invalid code on c# side #2582

cNori opened this issue May 10, 2024 · 5 comments · Fixed by #2591
Labels
bug Something isn't working scripting tools
Milestone

Comments

@cNori
Copy link
Contributor

cNori commented May 10, 2024

Issue description:
error CS0426: The type name 'Item' does not exist in the type 'Item.AttributeMarshaller'
error CS0411: The type arguments for method 'NativeInterop.ConvertArray<TSrc, TDst>(Span, Func<TSrc, TDst>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Steps to reproduce:

  • create script structure like this
Item : public Script
{
   struct Attribute : ...
   {

   };
};
struct RuntimeItem  : ...
{
   API_FIELD() Array<Item::Attribute> Attributes;
};

compile
get the errors

[edit]
genereted ouput

        internal static void Free(RuntimeItemInternal unmanaged)
        {
            ManagedString.Free(unmanaged.Name);
            if (unmanaged.m_ItemAsset != IntPtr.Zero) { ManagedHandle.FromIntPtr(unmanaged.m_ItemAsset).Free(); }
            if (unmanaged.Attributes != IntPtr.Zero) { ManagedHandle handle = ManagedHandle.FromIntPtr(unmanaged.Attributes); Span<Item.AttributeMarshaller.Item.AttributeInternal> values = (Unsafe.As<ManagedArray>(handle.Target)).ToSpan<Item.AttributeMarshaller.Item.AttributeInternal>(); foreach (var value in values) { Item.AttributeMarshaller.Free(value); } (Unsafe.As<ManagedArray>(handle.Target)).Free(); handle.Free(); }
        }
@GoaLitiuM
Copy link
Contributor

GoaLitiuM commented May 10, 2024

The following compiles just fine, are you missing API_STRUCT() from the Attribute struct?

API_CLASS() class GAME_API Item : public Script
{
API_AUTO_SERIALIZATION();
DECLARE_SCRIPTING_TYPE(Item);

    API_STRUCT() struct GAME_API Attribute
    {
        DECLARE_SCRIPTING_TYPE_MINIMAL(Attribute);
    };

    // [Script]
    void OnEnable() override;
    void OnDisable() override;
    void OnUpdate() override;
};

API_STRUCT() struct GAME_API RuntimeItem
{
    DECLARE_SCRIPTING_TYPE_MINIMAL(RuntimeItem);
    API_FIELD() Array<Item::Attribute> Attributes;
};

@cNori
Copy link
Contributor Author

cNori commented May 10, 2024

The following compiles just fine, are you missing API_STRUCT() from the Attribute struct?

API_CLASS() class GAME_API Item : public Script
{
API_AUTO_SERIALIZATION();
DECLARE_SCRIPTING_TYPE(Item);

    API_STRUCT() struct GAME_API Attribute
    {
        DECLARE_SCRIPTING_TYPE_MINIMAL(Attribute);
    };

    // [Script]
    void OnEnable() override;
    void OnDisable() override;
    void OnUpdate() override;
};

API_STRUCT() struct GAME_API RuntimeItem
{
    DECLARE_SCRIPTING_TYPE_MINIMAL(RuntimeItem);
    API_FIELD() Array<Item::Attribute> Attributes;
};

I have it in the source but i striped from ishue for redability

[Edit] DECLARE_SCRIPTING_TYPE_MINIMAL is incorect for struct btw

Compiler on c# is yeling abaut this
Item.AttributeMarshaller.Item.AttributeInternal
It needs to be like this
Item.AttributeMarshaller.AttributeInternal

@mtszkarbowiak
Copy link
Contributor

I think, for structs you should use DECLARE_SCRIPTING_TYPE_STRUCTURE.

@cNori
Copy link
Contributor Author

cNori commented May 11, 2024

found the place for a patch
BindingsGenerator.CSharp.cs:~1640
this will fix it

                        string originalElementType = originalType[0..^2];

                        if (internalType)
                        {
                            // Marshal blittable array elements back to original non-blittable elements
                            string originalElementTypeMarshaller = originalElementType + "Marshaller";
                            //[Nori_SC note]
                            //Find all characters after last . as a example if the c++ type is Class.Struct it will generate a invalid c# code
                            //with will look like this <Class>.<Struct>Marshaller.<Class>.<Struct>Internal
                            //valid code looks like this <Class>.<Struct>Marshaller.<Struct>Internal

                            var startindex = originalElementType.LastIndexOf('.') + 1;

                            string internalElementType = $"{originalElementTypeMarshaller}.{originalElementType[startindex..]}Internal";

@GoaLitiuM
Copy link
Contributor

The final code that reproduces the issue:

API_CLASS() class GAME_API Item : public Script
{
API_AUTO_SERIALIZATION();
DECLARE_SCRIPTING_TYPE(Item);

    API_STRUCT() struct GAME_API Attribute
    {
        DECLARE_SCRIPTING_TYPE_MINIMAL(Attribute);
        API_FIELD() String foo;
    };

    // [Script]
    void OnEnable() override;
    void OnDisable() override;
    void OnUpdate() override;
};

API_STRUCT() struct GAME_API RuntimeItem
{
    DECLARE_SCRIPTING_TYPE_MINIMAL(RuntimeItem);
    API_FIELD() Array<Item::Attribute> Attributes;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working scripting tools
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants