【问题标题】:Marshal.SizeOf(strurtureType) Always throws errorMarshal.SizeOf(sturtureType) 总是抛出错误
【发布时间】:2013-10-11 11:54:45
【问题描述】:

下面是我的代码sn-p

class Program
{
    static void Main(string[] args)
    {
        Program.GetState(new State() { enabled = true, currentLimit = 30 });
    }

    private static void GetState(State result)
    {
        IntPtr Ptr = Marshal.AllocHGlobal(Marshal.SizeOf(result));
        Marshal.StructureToPtr(result, Ptr, false);
    }
}

[StructLayout(LayoutKind.Sequential)]
public struct State
{
    [MarshalAsAttribute(UnmanagedType.I8)]
    public uint currentLimit;
    [MarshalAsAttribute(UnmanagedType.I1)]
    public bool enabled;
}

它总是抛出一个错误,即

类型“MarshellingStructureSize.State”不能作为 非托管结构;无法计算出有意义的大小或偏移量。

我的意图是通过 pInvoke 发送本机 DLL 的结构,但是当我尝试通过 Marshal 在托管代码中为我的结构分配内存时,它总是抛出上述错误。

任何帮助将不胜感激。

【问题讨论】:

  • 因为它与 pinvoking 本机 dll 部分相关,因此有用的点也可以来自 C++ 社区。​​span>
  • 问题是 currentLimit 的 MarshalAsAttribute(UnmanagedType.I8)。 C# 中的 uint 只有 4 个字节。将属性更改为 UnmangedType.U4。

标签: c# c++ .net pinvoke


【解决方案1】:

uint 实际上是System.UInt32 的别名,它占用内存中的 4 个字节。我认为currentLimit 无法在内存中转换为 8 个字节,这就是你得到错误的原因。

[MarshalAsAttribute(UnmanagedType.I8)]
public uint currentLimit;

I8 用于有符号的 8 字节整数。尝试将其更改为 U4 或 I4。

[MarshalAsAttribute(UnmanagedType.U4)]
public uint currentLimit;

或者按照@Hans Passant 的建议将currentLimit 的类型更改为ulong。

[MarshalAsAttribute(UnmanagedType.I8)] //or U8 
public ulong currentLimit;

这行得通。

【讨论】:

  • 对,或者把它变成ulong。
  • @HansPassant 当然,这取决于 OP 的需要。 :) 我会更新我的答案谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-26
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 2013-01-25
相关资源
最近更新 更多