Skip to content

Declaring a std::string member of a type marked CS_VALUE generates invalid C# #1217

Open
@akutruff

Description

@akutruff
Brief Description

Using std::string in a typical class compiles, however, when marking a type with CS_VALUE, the C# compiler complains about unfixed expressions.

OS: Windows / OS X / Linux (include version and/or distro)

Windows, VS 2019

Used headers

#include <string>

Used settings

Using latest nuget package

Target: MSVC/GCC/Clang

Other settings

Stack trace or incompilable generated code

C# compilation error

Error	CS0212	You can only take the address of an unfixed expression inside of a fixed statement initializer	

The struct in the cpp.

	struct MAPPING_API CS_VALUE_TYPE ValueTypeWithStdString
	{
		std::string ConfigPath;

		ValueTypeWithStdString(const std::string& configPath);
	};

The generated C#

       // DEBUG: struct MAPPING_API CS_VALUE_TYPE ValueTypeWithStdString
// DEBUG: 	{
// DEBUG: 		std::string ConfigPath;
// DEBUG: 
// DEBUG: 		ValueTypeWithStdString(const std::string& configPath);
// DEBUG: 	}
        public unsafe partial struct ValueTypeWithStdString
        {
            [StructLayout(LayoutKind.Explicit, Size = 32)]
            public partial struct __Internal
            {
                [FieldOffset(0)]
                internal global::Std.BasicString.__Internalc__N_std_S_basic_string__C___N_std_S_char_traits__C___N_std_S_allocator__C ConfigPath;

                [SuppressUnmanagedCodeSecurity]
                [DllImport("mapping", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
                    EntryPoint="??0ValueTypeWithStdString@mapping@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z")]
                internal static extern global::System.IntPtr ctor(global::System.IntPtr __instance, global::System.IntPtr configPath);

                [SuppressUnmanagedCodeSecurity]
                [DllImport("mapping", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
                    EntryPoint="??0ValueTypeWithStdString@mapping@@QEAA@AEBU01@@Z")]
                internal static extern global::System.IntPtr cctor_1(global::System.IntPtr __instance, global::System.IntPtr _0);

                [SuppressUnmanagedCodeSecurity]
                [DllImport("mapping", CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
                    EntryPoint="??1ValueTypeWithStdString@mapping@@QEAA@XZ")]
                internal static extern void dtor(global::System.IntPtr __instance, int delete);
            }

            private ValueTypeWithStdString.__Internal __instance;
            internal ValueTypeWithStdString.__Internal __Instance { get { return __instance; } }

            internal static global::Mapping.Autogen.Mapping.ValueTypeWithStdString __CreateInstance(global::System.IntPtr native, bool skipVTables = false)
            {
                return new global::Mapping.Autogen.Mapping.ValueTypeWithStdString(native.ToPointer(), skipVTables);
            }

            internal static global::Mapping.Autogen.Mapping.ValueTypeWithStdString __CreateInstance(global::Mapping.Autogen.Mapping.ValueTypeWithStdString.__Internal native, bool skipVTables = false)
            {
                return new global::Mapping.Autogen.Mapping.ValueTypeWithStdString(native, skipVTables);
            }

            private ValueTypeWithStdString(global::Mapping.Autogen.Mapping.ValueTypeWithStdString.__Internal native, bool skipVTables = false)
                : this()
            {
                __instance = native;
            }

            private ValueTypeWithStdString(void* native, bool skipVTables = false) : this()
            {
                __instance = *(global::Mapping.Autogen.Mapping.ValueTypeWithStdString.__Internal*) native;
            }

            // DEBUG: ValueTypeWithStdString(const std::string& configPath)
            public ValueTypeWithStdString(string configPath)
                : this()
            {
                var __basicString0 = new global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>();
                global::Std.BasicStringExtensions.Assign(__basicString0, configPath);
                var __arg0 = __basicString0.__Instance;
                fixed (__Internal* __instancePtr = &__instance)
                {
                    __Internal.ctor(new global::System.IntPtr(__instancePtr), __arg0);
                    __basicString0.Dispose(false);
                }
            }

            // DEBUG: ValueTypeWithStdString
            public ValueTypeWithStdString(global::Mapping.Autogen.Mapping.ValueTypeWithStdString _0)
                : this()
            {
                var ____arg0 = _0.__Instance;
                var __arg0 = new global::System.IntPtr(&____arg0);
                fixed (__Internal* __instancePtr = &__instance)
                {
                    __Internal.cctor_1(new global::System.IntPtr(__instancePtr), __arg0);
                }
            }

            public static implicit operator global::Mapping.Autogen.Mapping.ValueTypeWithStdString(string configPath)
            {
                return new global::Mapping.Autogen.Mapping.ValueTypeWithStdString(configPath);
            }

            public string ConfigPath
            {
                get
                {
                    var __basicStringRet0 = global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>.__CreateInstance(__instance.ConfigPath);
                    var __stringRet0 = global::Std.BasicStringExtensions.CStr(__basicStringRet0);
                    __basicStringRet0.Dispose(false);
                    return __stringRet0;
                }

                set
                {
                    global::Std.BasicStringExtensions.__Internal.Assign(new global::System.IntPtr(&__instance.ConfigPath), value);
                }
            }
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions