Skip to content

Expose CLong, CULong, and NFloat interchange types #13788

Closed
@tannergooding

Description

@tannergooding

Rationale

There exists a few common interchange types which are variable sized. Unlike many of the other types, it is non-trivial for a user to define these types themselves and even if they did, there are some calling conventions where structs are not marshaled the same as the underlying T they may wrap.

These types include long and unsigned long types defined by C/C++ which have variable size depending on the target platform/architecture. On Windows, these types are always 4-bytes and are equivalent to int/uint in C#. On Unix, however, these types are 4-bytes or 8-bytes depending on if you are targeting a 32-bit or 64-bit platform which makes them equivalent to nint/nuint.

Likewise Apple defines CGFloat which is float on 32-bit systems and double on 64-bit systems.

As such, I propose we expose minimal types that are recognized by the runtime and are handled as if they were the corresponding underlying primitive type to avoid the ABI issues. These types are explicitly very minimal and do not provide "common" operations such as parsing, formatting, or even simple operators.

Proposal

namespace System.Runtime.InteropServices
{
    public readonly struct CLong : IEquatable<CLong>
    {
        public CLong(nint value);

        public nint Value { get; }

        public override bool Equals(object o);
        public bool Equals(CLong other);

        public override int GetHashCode();

        public override string ToString();
    }

    public readonly struct CULong : IEquatable<CULong>
    {
        public CULong(nuint value);

        public nuint Value { get; }

        public override bool Equals(object o);
        public bool Equals(CULong other);

        public override int GetHashCode();

        public override string ToString();
    }

    public readonly struct NFloat : IEquatable<NFloat>
    {
        public NFloat(double value);

        public double Value { get; }

        public override bool Equals(object o);
        public bool Equals(NFloat other);

        public override int GetHashCode();

        public override string ToString();
    }
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions