将 [StructLayout] 替换为不使用 System.Runtime.InteropServices 的内容?

发布于 2024-07-27 00:59:17 字数 2182 浏览 8 评论 0原文

我没有低级编程的经验,我需要这段代码不使用 [StructLayout(LayoutKind.Explicit)]。 我的网站在共享主机上运行并处于中等信任状态。 所以如果这段代码在那里,它就不会运行。

更新: 我在八叉树中使用它来量化 png 文件。

有谁知道解决办法吗?

更新 新问题在这里 => 有什么办法吗图像量化安全且无需编组?

/// <summary>
        /// Struct that defines a 32 bpp colour
        /// </summary>
        /// <remarks>
        /// This struct is used to read data from a 32 bits per pixel image
        /// in memory, and is ordered in this manner as this is the way that
        /// the data is layed out in memory
        /// </remarks>
        [StructLayout(LayoutKind.Explicit)]
        public struct Color32
        {

            public Color32(IntPtr pSourcePixel)
            {
                this = (Color32)Marshal.PtrToStructure(pSourcePixel, typeof(Color32));

            }

            /// <summary>
            /// Holds the blue component of the colour
            /// </summary>
            [FieldOffset(0)]
            public byte Blue;
            /// <summary>
            /// Holds the green component of the colour
            /// </summary>
            [FieldOffset(1)]
            public byte Green;
            /// <summary>
            /// Holds the red component of the colour
            /// </summary>
            [FieldOffset(2)]
            public byte Red;
            /// <summary>
            /// Holds the alpha component of the colour
            /// </summary>
            [FieldOffset(3)]
            public byte Alpha;

            /// <summary>
            /// Permits the color32 to be treated as an int32
            /// </summary>
            [FieldOffset(0)]
            public int ARGB;

            /// <summary>
            /// Return the color for this Color32 object
            /// </summary>
            public Color Color
            {
                get { return Color.FromArgb(Alpha, Red, Green, Blue); }
            }
        }

I have no experience with low level programing and I need this piece of code to not use [StructLayout(LayoutKind.Explicit)]. My site runs on a shared host and in medium trust.
So it won't run if this code is in there.

Update:
I'm using this inside a Octree to Quantize a png file.

Does anyone know a work around?

Update
New question here => Is there any way to do Image Quantization safely and with no Marshalling?

/// <summary>
        /// Struct that defines a 32 bpp colour
        /// </summary>
        /// <remarks>
        /// This struct is used to read data from a 32 bits per pixel image
        /// in memory, and is ordered in this manner as this is the way that
        /// the data is layed out in memory
        /// </remarks>
        [StructLayout(LayoutKind.Explicit)]
        public struct Color32
        {

            public Color32(IntPtr pSourcePixel)
            {
                this = (Color32)Marshal.PtrToStructure(pSourcePixel, typeof(Color32));

            }

            /// <summary>
            /// Holds the blue component of the colour
            /// </summary>
            [FieldOffset(0)]
            public byte Blue;
            /// <summary>
            /// Holds the green component of the colour
            /// </summary>
            [FieldOffset(1)]
            public byte Green;
            /// <summary>
            /// Holds the red component of the colour
            /// </summary>
            [FieldOffset(2)]
            public byte Red;
            /// <summary>
            /// Holds the alpha component of the colour
            /// </summary>
            [FieldOffset(3)]
            public byte Alpha;

            /// <summary>
            /// Permits the color32 to be treated as an int32
            /// </summary>
            [FieldOffset(0)]
            public int ARGB;

            /// <summary>
            /// Return the color for this Color32 object
            /// </summary>
            public Color Color
            {
                get { return Color.FromArgb(Alpha, Red, Green, Blue); }
            }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蔚蓝源自深海 2024-08-03 00:59:17

Marshal.PtrToStructure 方法 (IntPtr, Type) 无论如何都不会工作,因为它需要

<前><代码>[SecurityPermissionAttribute(
安全操作.LinkDemand,
标志 = SecurityPermissionFlag.UnmanagedCode)]

您可以自己安全地处理偏移量,但您必须在不使用 Marshal 的情况下完成此操作。
为了简单起见,我还建议改用 uint。

public struct Color32
{
    const uint BlueMask  = 0xFF000000;       
    const uint GreenMask = 0x00FF0000;
    const uint RedMask   = 0x0000FF00;
    const uint AlphaMask = 0x000000FF;
    const int BlueShift  = 24;       
    const int GreenShift = 16;
    const int RedShift   = 8;
    const int AlphaShift = 0;

    private byte GetComponent(uint mask, int shift)
    {
        var b = (this.ARGB & mask);
        return (byte) (b >> shift);            
    } 

    private void SetComponent(int shift, byte value)
    {
        var b = ((uint)value) << shift
        this.ARGB |= b;
    } 

    public byte Blue 
    {
        get { return GetComponent(BlueMask, BlueShift); }
        set { SetComponent(BlueShift, value); }
    }

    public byte Green
    {
        get { return GetComponent(GreenMask, GreenShift); }
        set { SetComponent(GreenShift, value); }
    }

    public byte Red
    {
        get { return GetComponent(RedMask, RedShift); }
        set { SetComponent(RedShift, value); }
    }

    public byte Alpha
    {
        get { return GetComponent(AlphaMask, AlphaShift); }
        set { SetComponent(AlphaShift, value); }
    }

    /// <summary>
    /// Permits the color32 to be treated as an UInt32
    /// </summary>
    public uint ARGB;

    /// <summary>
    /// Return the color for this Color32 object
    /// </summary>
    public Color Color
    {
        get { return Color.FromArgb(Alpha, Red, Green, Blue); }
    }
}

然而,您似乎想要做的是将一个字节顺序的 int32 转换为相反的顺序。
为此,您有 System.Net.IPAddress.HostToNetworkOrder< /a> (在这方面令人讨厌的用法,您只是使用它来反转字节序,而不是具体说明您想要的顺序)

因此,如果您可以将输入数据读取为简单的 int32 值,那么:

static Color FromBgra(int bgra)
{
    return Color.FromArgb(System.Net.IPAddress.HostToNetworkOrder(bgra));
}

这可能会简单得多。

Marshal.PtrToStructure Method (IntPtr, Type) won't work anyway since it requires

[SecurityPermissionAttribute(
    SecurityAction.LinkDemand, 
    Flags = SecurityPermissionFlag.UnmanagedCode)]

You could deal with the offsets yourself safely, but you would have to do it without using Marshal.
I suggest also moving to using uints for simplicity.

public struct Color32
{
    const uint BlueMask  = 0xFF000000;       
    const uint GreenMask = 0x00FF0000;
    const uint RedMask   = 0x0000FF00;
    const uint AlphaMask = 0x000000FF;
    const int BlueShift  = 24;       
    const int GreenShift = 16;
    const int RedShift   = 8;
    const int AlphaShift = 0;

    private byte GetComponent(uint mask, int shift)
    {
        var b = (this.ARGB & mask);
        return (byte) (b >> shift);            
    } 

    private void SetComponent(int shift, byte value)
    {
        var b = ((uint)value) << shift
        this.ARGB |= b;
    } 

    public byte Blue 
    {
        get { return GetComponent(BlueMask, BlueShift); }
        set { SetComponent(BlueShift, value); }
    }

    public byte Green
    {
        get { return GetComponent(GreenMask, GreenShift); }
        set { SetComponent(GreenShift, value); }
    }

    public byte Red
    {
        get { return GetComponent(RedMask, RedShift); }
        set { SetComponent(RedShift, value); }
    }

    public byte Alpha
    {
        get { return GetComponent(AlphaMask, AlphaShift); }
        set { SetComponent(AlphaShift, value); }
    }

    /// <summary>
    /// Permits the color32 to be treated as an UInt32
    /// </summary>
    public uint ARGB;

    /// <summary>
    /// Return the color for this Color32 object
    /// </summary>
    public Color Color
    {
        get { return Color.FromArgb(Alpha, Red, Green, Blue); }
    }
}

however it would appear that what you want to do is convert an int32 in one byte order to the reverse.
For this you have System.Net.IPAddress.HostToNetworkOrder (nasty usage in this regard, you are simply using it to reverse the endianess rather than being specific about which ordering you intend)

so if you could read your input data as simple int32 values then do:

static Color FromBgra(int bgra)
{
    return Color.FromArgb(System.Net.IPAddress.HostToNetworkOrder(bgra));
}

This would likely be much simpler.

时光病人 2024-08-03 00:59:17

与本机代码和内存进行互操作本质上是不安全的操作。 对 Marshal 类的任何调用也将失败。 除非您具有完全信任级别,否则您无法访问内存或执行任何互操作。

Interoperating with native code and memory is an inherently unsafe operation. Any calls to the Marshal class will fail as well. You can't access the memory, or do any Interop unless you have full trust level.

滥情哥ㄟ 2024-08-03 00:59:17

您可以只存储 int ARGB,并使用 BitConverter将其转换为 4 个字节以供颜色返回。

更好的是,只需存储 int,并使用 Color.FromArgb(Int32)。

这两种方法都不需要存储各个字节,因此您可以完全消除 StructLayout 属性。

You could just store the int ARGB, and use a BitConverter to convert it to the 4 bytes for your color return.

Even better, just store the int, and use Color.FromArgb(Int32).

Both of these approaches eliminate the need to store the individual bytes, so you can completely eliminate the StructLayout attribute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文