dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.45k stars 4.76k forks source link

NativeAOT Convert C# Struct to C++ Pointer Failed #98922

Closed dongfengxin closed 9 months ago

dongfengxin commented 9 months ago

Description

NativeAOT Convert C# Struct to C++ Pointer Failed

There is a C# Struct like this :

[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct OPEN_SETTING_EXT
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public SERVER_INFO[] siServer;

    public uint nServerNum;

    public DataMsgHandler pfnMsgHandler;

    public SystemMsgHandler pfnSysMsgNotify;

    public IntPtr szMarkets;

    public IntPtr szResvMarkets;

    public IntPtr szSubScriptions;

    public uint nTypeFlags;

    public int nTime;

    public uint nConnectionID;
}

and will be Convert to a C++ Intptr with the fllowing method:

    [RequiresDynamicCode("Calls System.Runtime.InteropServices.Marshal.StructureToPtr(Object, nint, Boolean)")]
    public static IntPtr CopyStructToGlobalMem(object obj, Type typeInfo)
    {
        IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeInfo));
        Marshal.StructureToPtr(obj, intPtr, fDeleteOld: false);
        return intPtr;
    }

last will be used like this:

            Console.WriteLine("Ready To Run CopyStructToGlobalMem");
            m_pSettings = LibWrapHelper.CopyStructToGlobalMem(m_openSetting_ext, typeof(TDF_OPEN_SETTING_EXT));
            Console.WriteLine("CopyStructToGlobalMem Runed");

Reproduction Steps

The Above function runs well in normal release way, but didnot runs well in NativeAOT.

Expected behavior

image

Actual behavior

image The Second line returns the failed message.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

huoyaoyuan commented 9 months ago

As the RequiresDynamicCode message says, StructureToPtr(Object) is unfriendly with AOT compiler. StructureToPtr<T> is the alternative.

Can you change the function to generic and see if it solves the problem?

    public static IntPtr CopyStructToGlobalMem<T>(T obj)
    {
        IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<T>());
        Marshal.StructureToPtr(obj, intPtr, fDeleteOld: false);
        return intPtr;
    }

In addition, please do not ignore AOT/trim warnings during NativeAOT publishing. Methods with RequiresDynamicCode are likely to break with AOT.

dongfengxin commented 9 months ago

As the RequiresDynamicCode message says, StructureToPtr(Object) is unfriendly with AOT compiler. StructureToPtr<T> is the alternative.

Can you change the function to generic and see if it solves the problem?

    public static IntPtr CopyStructToGlobalMem<T>(T obj)
    {
        IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<T>());
        Marshal.StructureToPtr(obj, intPtr, fDeleteOld: false);
        return intPtr;
    }

In addition, please do not ignore AOT/trim warnings during NativeAOT publishing. Methods with RequiresDynamicCode are likely to break with AOT.

Thank you so much! It Works Well.

dongfengxin commented 9 months ago

As the RequiresDynamicCode message says, StructureToPtr(Object) is unfriendly with AOT compiler. StructureToPtr<T> is the alternative.

Can you change the function to generic and see if it solves the problem?

    public static IntPtr CopyStructToGlobalMem<T>(T obj)
    {
        IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf<T>());
        Marshal.StructureToPtr(obj, intPtr, fDeleteOld: false);
        return intPtr;
    }

In addition, please do not ignore AOT/trim warnings during NativeAOT publishing. Methods with RequiresDynamicCode are likely to break with AOT.

And there a a lot of waring, further more , I with little experience of nativeaot update, sometimes, did not no the solution action with the warnings。 lot of knowledge to learn with nativeaot.

ivdiazsa commented 9 months ago

Since this case was defined to not be fully compatible with NativeAOT and the alternative suggestion worked, would it be reasonable to close this issue?