Home icon indicating copy to clipboard operation
Home copied to clipboard

Reflection/invoking a 'struct' object will throw an exception

Open bytewizer opened this issue 3 years ago • 3 comments

Library/API/IoT binding

System

Visual Studio version

VS2022 17.2.1

.NET nanoFramework extension version

2022.0.0.19

Target name(s)

ST_NUCLEO144_F746ZG, M5Core2

Firmware version

1.8.0.112, 1.8.0.323

Device capabilities

No response

Description

When using reflection to invoke a 'struct' object the object is created without error, but the object is not correctly created. If you used the exact same code to create a 'class' object the object is created correctly. See code comments below:

How to reproduce

This code will run on the full dotnet stack perfectly and I could not find anywhere that reflection/invoking a 'struct' object should not work. Also, when the object is created you can see the object in the debugger but even trying to use a simple object.GetType() method it will throw and exception.

Expected behaviour

This code should run without error.

Screenshots

No response

Sample project or code

using System;

namespace Testing
{
    public class Program
    {
        public static void Main()
        {
            // This works perfectly and object is created as expected
            var classInstance = typeof(ClassFakeService).GetConstructor(new Type[] { typeof(FakeObject) }).Invoke(new object[] { new FakeObject() });

            var classArray = new object[1] { classInstance };
            var newClassArray = new object[1];

            Array.Copy(classArray, newClassArray, classArray.Length);
            
            // This dosn't throw and error when created but the parm object is null
            var structInstance = typeof(StructFakeService).GetConstructor(new Type[] { typeof(FakeObject) }).Invoke(new object[] { new FakeObject() });
            
            // As soon as you try to use this object in any way it throws an execption
            var structArray = new object[1] { structInstance };
            var newStrctArray = new object[1];

            Array.Copy(structArray, newStrctArray, structArray.Length);
        }

        public class FakeObject 
        {
        }

        public struct StructFakeService 
        {
            private readonly FakeObject _fakeObject;

            public StructFakeService(FakeObject fakeObject)
            {
                _fakeObject = fakeObject;
            }
        }

        public class ClassFakeService
        {
            private readonly FakeObject _fakeObject;

            public ClassFakeService(FakeObject fakeObject)
            {
                _fakeObject = fakeObject;
            }
        }
    }
}

Aditional information

No response

bytewizer avatar Jun 25 '22 14:06 bytewizer

Behavior confirmed. It's happening because the CLR is executing the IL new as if it was a class, which is incorrect because structs are value types.

josesimoes avatar Sep 28 '22 17:09 josesimoes

Can nanoFramework call the dll generated by C

mimimiaomiao1 avatar Nov 24 '22 05:11 mimimiaomiao1

Can nanoFramework call the dll generated by C

Sure, you have to build it in the image, it's not really a dll, more like a native element written in C. This is how all nanoFramework is built!

You have the documentation here: https://docs.nanoframework.net/content/architecture/nanoclr-stub-args.html

Ellerbach avatar Nov 24 '22 07:11 Ellerbach